[llvm-commits] CVS: llvm/test/Programs/MultiSource/Applications/obsequi/COPYRIGHT GPL LICENSE.TXT Makefile README consts.h cppflags.h display.c does_x_win.c globals.h hash.c init.c interface.h macros.h move_gen.c move_sort.c negamax.c obsequi.c position_values.c structs.h tables.c toggle_move.c traits.c utils.c utils.h

John Criswell criswell at cs.uiuc.edu
Tue May 11 14:35:03 PDT 2004


Changes in directory llvm/test/Programs/MultiSource/Applications/obsequi:

COPYRIGHT added (r1.1)
GPL added (r1.1)
LICENSE.TXT added (r1.1)
Makefile added (r1.1)
README added (r1.1)
consts.h added (r1.1)
cppflags.h added (r1.1)
display.c added (r1.1)
does_x_win.c added (r1.1)
globals.h added (r1.1)
hash.c added (r1.1)
init.c added (r1.1)
interface.h added (r1.1)
macros.h added (r1.1)
move_gen.c added (r1.1)
move_sort.c added (r1.1)
negamax.c added (r1.1)
obsequi.c added (r1.1)
position_values.c added (r1.1)
structs.h added (r1.1)
tables.c added (r1.1)
toggle_move.c added (r1.1)
traits.c added (r1.1)
utils.c added (r1.1)
utils.h added (r1.1)

---
Log message:

Addition of the obsequi program.  This program solves domineering boards.



---
Diffs of the changes:  (+4819 -0)

Index: llvm/test/Programs/MultiSource/Applications/obsequi/COPYRIGHT
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/COPYRIGHT:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/COPYRIGHT	Tue May 11 14:34:12 2004
***************
*** 0 ****
--- 1,21 ----
+ Obsequi is a program which is able to solve the game of domineering
+   for various board sizes.
+ 
+ Copyright (C) 2002 Nathan Bullock
+ 
+ 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
+ 
+ bullock at cs.ualberta.ca
+ jonathan at cs.ualberta.ca


Index: llvm/test/Programs/MultiSource/Applications/obsequi/GPL
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/GPL:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/GPL	Tue May 11 14:34:12 2004
***************
*** 0 ****
--- 1,340 ----
+ 		    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.
+ 
+     <one line to give the program's name and a brief idea of what it does.>
+     Copyright (C) <year>  <name of author>
+ 
+     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.
+ 
+   <signature of Ty Coon>, 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.


Index: llvm/test/Programs/MultiSource/Applications/obsequi/LICENSE.TXT
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/LICENSE.TXT:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/LICENSE.TXT	Tue May 11 14:34:12 2004
***************
*** 0 ****
--- 1,5 ----
+ Obsequi
+ ------------------------------------------------------------------------------
+ Obsequi is licensed under the GNU General Public License.  Please see the file
+ COPYRIGHT and GPL for more information.
+ 


Index: llvm/test/Programs/MultiSource/Applications/obsequi/Makefile
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/Makefile:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/Makefile	Tue May 11 14:34:12 2004
***************
*** 0 ****
--- 1,8 ----
+ LEVEL = ../../../../..
+ PROG = Obsequi
+ CPPFLAGS += -DCOUNTBITS16 -DLASTBIT16 -DCOUNTMOVES_TABLE -DHASHCODEBITS=23
+ CPPFLAGS += -DTWO_STAGE_GENERATION
+ LDFLAGS = -lsupc++
+ LIBS += -lsupc++
+ STDIN_FILENAME=$(BUILD_SRC_DIR)/input
+ include ../../Makefile.multisrc


Index: llvm/test/Programs/MultiSource/Applications/obsequi/README
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/README:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/README	Tue May 11 14:34:12 2004
***************
*** 0 ****
--- 1,23 ----
+ obsequi - latin for compliance, indulgence, submission, pliancy.
+ 
+ This program is able to play and solve domineering boards.
+ Currently it can solve 9x9 and larger boards with a single processor.
+ 
+ To compile cd to the directory "obsequi", type make.
+ 
+ Should work, if not, you must be using a different compiler or
+ libraries. (I use gcc and glibc).
+ 
+ There isn't really any documentation for obsequi (sorry).
+ 
+ To get it to solve an 8x8 board use:
+ echo "solve rows 8 cols 8 V" | ./Obsequi
+ 
+ You can also pre-place blocks on the board.
+ The V says it is verticals turn first.
+ There are a number of run time options and compile time options, the
+ compile time options are in cppflags.raw (don't change the other cppflags*
+ files they are automatically changed.)
+ 
+ 
+ 


Index: llvm/test/Programs/MultiSource/Applications/obsequi/consts.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/consts.h:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/consts.h	Tue May 11 14:34:12 2004
***************
*** 0 ****
--- 1,48 ----
+ 
+ 
+ //########################################################
+ // Constants which we use.
+ // Any constants which we commonly change or try to tweak
+ //   should be in cppflags.raw.
+ //########################################################
+ 
+ // max number of empty squares which should ever exist is 256
+ //  therefore we could possible get close to this number of moves.
+ #define MAXMOVES 256
+ 
+ // Player stuff. (Used for example with g_board to get the current player).
+ #define HORIZONTAL    0
+ #define VERTICAL      1
+ #define PLAYER_MASK   1
+ 
+ // Used with g_board_size (to get num of rows and num of cols).
+ #define ROW_INDEX  HORIZONTAL
+ #define COL_INDEX  VERTICAL
+ 
+ 
+ #define LOWER   0
+ #define EXACT   1
+ #define UPPER   2
+ 
+ 
+ // blah
+ #define ERASE_NEXT_BIT  0x80000000;
+ #define NEXT_BIT        0x00010000;
+ 
+ //########################################################
+ // Constants used in conjuction with the transposition table
+ //   and the zobrist values.
+ //########################################################
+ 
+ // HASHCODEBITS should already be defined.
+ #ifndef HASHCODEBITS
+ #error "HASHCODEBITS must be defined.\n"
+ #endif
+ 
+ // It should have a value of between 0 and 31.
+ #if ! (HASHCODEBITS > 0 && HASHCODEBITS < 31)
+ #error "Invalid value for HASHCODEBITS, it should be a value from 1 - 30."
+ #endif
+ 
+ #define HASHSIZE (1 << HASHCODEBITS)
+ #define HASHMASK (HASHSIZE - 1)


Index: llvm/test/Programs/MultiSource/Applications/obsequi/cppflags.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/cppflags.h:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/cppflags.h	Tue May 11 14:34:12 2004
***************
*** 0 ****
--- 1,10 ----
+ // This file is automatically generated from CPPFLAGS_raw
+ 
+ char option_string[] = 
+ "-Wall -O2\n"
+ "-DCOUNTBITS16\n"
+ "-DLASTBIT16\n"
+ "-DCOUNTMOVES_TABLE\n"
+ "-DHASHCODEBITS=23\n"
+ "-DTWO_STAGE_GENERATION\n"
+ ;


Index: llvm/test/Programs/MultiSource/Applications/obsequi/display.c
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/display.c:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/display.c	Tue May 11 14:34:12 2004
***************
*** 0 ****
--- 1,333 ----
+ 
+ 
+ #include "globals.h"
+ 
+ 
+ //########################################################
+ // Sanity check functions.
+ // These functions try to do a quick check of some set of
+ //   information. They crash and burn if the check fails.
+ //########################################################
+ 
+ static void
+ check_hashkey_bit_set(Hash_Key key, s32bit index)
+ {
+   if(! (key.key[index/32] & NTH_BIT(index%32)) ){
+ 
+     printf("%d", index);
+     
+     print_bitboard(HORIZONTAL);
+ 
+     print_hashkey(key);
+ 
+     fatal_error(1, "HashKey Incorrect.\n");
+   }
+ }
+ 
+ static void
+ check_hashkey_bit_not_set(Hash_Key key, s32bit index)
+ {
+   if( (key.key[index/32] & NTH_BIT(index%32)) ){
+ 
+     printf("%d", index);
+     
+     print_bitboard(HORIZONTAL);
+ 
+     print_hashkey(key);
+ 
+     fatal_error(1, "HashKey Incorrect.\n");
+   }
+ }
+ 
+ static void
+ check_hashkey_code(Hash_Key key)
+ {
+   s32bit i, j, index, n_rows, n_cols, code;
+   
+   n_rows = g_board_size[HORIZONTAL], n_cols = g_board_size[VERTICAL];
+ 
+   code = key.code;
+   
+   for(i = 0; i < n_rows; i++)
+     for(j = 0; j < n_cols; j++){
+       index = (i*n_cols) + j;
+       if(key.key[index/32] & NTH_BIT(index%32))
+         code ^= g_zobrist[i+1][j+1];
+     }
+   
+   if(code != 0){
+     fatal_error(1, "Invalid hash code.\n");
+   }
+ }
+ 
+ 
+ 
+ //========================================================
+ // This function checks to make sure hash codes
+ //   and keys are correct.
+ //========================================================
+ extern void
+ check_hash_code_sanity()
+ {
+   s32bit i, j, index, n_rows, n_cols;
+   
+   n_rows = g_board_size[HORIZONTAL], n_cols = g_board_size[VERTICAL];
+   
+   for(i = 0; i < n_rows; i++)
+     for(j = 0; j < n_cols; j++)
+       if(g_board[HORIZONTAL][i+1] & NTH_BIT(j+1)) {
+ 
+         index = (i*n_cols)+j;
+         check_hashkey_bit_set(g_norm_hashkey, index);
+         
+         index = (i*n_cols)                  + (n_cols - j - 1);
+         check_hashkey_bit_set(g_flipV_hashkey, index);
+         
+         index = ( (n_rows - i - 1) *n_cols) + j;
+         check_hashkey_bit_set(g_flipH_hashkey, index);
+         
+         index = ( (n_rows - i - 1) *n_cols) + (n_cols - j - 1);
+         check_hashkey_bit_set(g_flipVH_hashkey, index);
+       } else {
+         index = (i*n_cols)+j;
+         check_hashkey_bit_not_set(g_norm_hashkey, index);
+         
+         index = (i*n_cols)                  + (n_cols - j - 1);
+         check_hashkey_bit_not_set(g_flipV_hashkey, index);
+         
+         index = ( (n_rows - i - 1) *n_cols) + j;
+         check_hashkey_bit_not_set(g_flipH_hashkey, index);
+         
+         index = ( (n_rows - i - 1) *n_cols) + (n_cols - j - 1);
+         check_hashkey_bit_not_set(g_flipVH_hashkey, index);
+       }
+ 
+   check_hashkey_code(g_norm_hashkey);
+   check_hashkey_code(g_flipV_hashkey);
+   check_hashkey_code(g_flipH_hashkey);
+   check_hashkey_code(g_flipVH_hashkey);
+ }
+ 
+ 
+ 
+ //========================================================
+ // This function compares the Horizontal board info to 
+ //  the vertical board info.
+ //========================================================
+ extern void
+ check_board_sanity()
+ {
+   s32bit i, j;
+   s32bit count;
+   
+   for(j = 0; j < g_board_size[HORIZONTAL] + 2; j++)
+     for(i = 0; i < g_board_size[VERTICAL] + 2; i++){
+       count = 0;
+       
+       if(g_board[VERTICAL][i] & NTH_BIT(j)) count++;
+       if(g_board[HORIZONTAL][j] & NTH_BIT(i)) count++;
+       
+       if(count == 1){
+         print_board(VERTICAL);
+         print_board(HORIZONTAL);    
+         
+         printf("%d %d - %d.\n", j, i, count);
+         
+         fatal_error(1, "Board is inconsistent.\n");
+       }
+     }
+ }
+ 
+ //========================================================
+ // Check the board info which we have to make sure that it
+ //  is accurate.
+ //========================================================
+ /*
+ extern void
+ check_info_sanity()
+ {
+ }*/
+ 
+ 
+ 
+ //########################################################
+ // Display functions.
+ // These functions print out some set of information in what
+ //   is hopefully a fairly readable format.
+ //########################################################
+ extern void
+ print_hashentry(s32bit index)
+ {
+   Hash_Entry entry = g_trans_table[index];
+   
+   printf("Hash entry: %d.\n", index);
+   printf(" Key:%8X:%8X:%8X:%8X, n:%u, d:%d, w:%d"
+          ", v:%d, t:%d, int:%d.\n",
+          entry.key[0], entry.key[1], entry.key[2], entry.key[3],
+          entry.nodes, entry.depth, entry.whos_turn,
+          entry.value, entry.type, entry.best_move);
+ }
+ 
+ 
+ extern void
+ print_board(s32bit player)
+ {
+   s32bit player_index;
+   s32bit row, col, i, j;
+   
+   player_index = player&PLAYER_MASK;
+   
+   row = g_board_size[player_index];
+   col = g_board_size[player_index^PLAYER_MASK];
+   
+   for(i = 0; i < row; i++){
+     for(j = 0; j < col; j++){
+       if(g_board[player_index][i+1] & NTH_BIT(j+1))
+         printf(" #");
+       else
+         printf(" 0");
+     }
+     printf("\n");
+   }
+ }
+ 
+ extern void
+ print_board_info(s32bit player)
+ {
+   s32bit  num_rows, num_cols, max_dim, i;
+   char    str[32][80], null_str[1] = "";
+ 
+   num_rows = g_board_size[HORIZONTAL];
+   num_cols = g_board_size[VERTICAL];
+   max_dim = MAX_TWO(num_rows, num_cols);
+     
+   sprintf(str[1], "Number of rows    = %d", g_board_size[HORIZONTAL]);
+   sprintf(str[2], "Number of columns = %d", g_board_size[VERTICAL]);
+   
+   printf("%7s %15s %15s\n",
+          null_str, "Vertical", "Horizontal");
+   printf("%7s %7s %7s %7s %7s\n",
+          null_str, "Real", "Safe", "Real", "Safe");
+ 
+   for(i = 0; i < max_dim; i++){
+     printf("%6d) %7d %7d %7d %7d  %s\n", i + 1,
+            g_info[VERTICAL][i+1].real, g_info[VERTICAL][i+1].safe,
+            g_info[HORIZONTAL][i+1].real, g_info[HORIZONTAL][i+1].safe,
+            (i < 2) ? str[i+1] : null_str);
+   }
+ 
+   printf("Totals: %7d %7d %7d %7d\n",
+          g_info_totals[VERTICAL].real, g_info_totals[VERTICAL].safe,
+          g_info_totals[HORIZONTAL].real, g_info_totals[HORIZONTAL].safe);
+ }
+ 
+ extern void
+ print_bitboard(s32bit player)
+ {
+   s32bit player_index;
+   s32bit i;
+     
+   player_index = player&PLAYER_MASK;
+   
+   for(i = 0; i < g_board_size[player_index] + 2; i++)
+     printf("%X\n", g_board[player_index][i]);
+ }
+ 
+ extern void
+ print_hashkey(Hash_Key key)
+ {
+   printf("Key: %8X:%8X:%8X:%8X, Code: %8X.\n",
+          key.key[0], key.key[1], key.key[2], key.key[3], key.code);
+ }
+ 
+ extern void
+ print_u64bit(u64bit val)
+ {
+   s32bit vals[10];
+   s32bit i = 0;
+   
+   do {
+     vals[i] = val % 1000;
+     val = val / 1000;
+     i++;
+   } while(val != 0);
+   
+   if(i > 10) fatal_error(1, "Too large???\n");
+   
+   printf("%d", vals[--i]);
+   
+   while(i != 0)
+     printf(",%3d", vals[--i]);
+ }
+ 
+ extern void
+ print_keyinfo(KeyInfo_s info, s32bit with)
+ {
+   if(info.bit1_index == -1) fatal_error(1, "bit1_index equal to -1");
+ 
+   if(with)
+     printf("%3d:%3d %8X ",
+            info.bit1_index, info.bit2_index, info.hash_code);
+   else
+     printf("%3d:%3d ",
+            info.bit1_index, info.bit2_index);
+ }
+ 
+ 
+ extern void
+ print_keyinfo_table(s32bit player, s32bit with_hashcode)
+ {
+   s32bit r, c;
+   
+   for(r = 0; r < 32; r++)
+     for(c = 0; c < 32; c++){
+       if(g_keyinfo[player][r][c].norm.bit1_index != -1){
+       
+         printf("(%2d,%2d)>>  ", r, c);
+ 
+         print_keyinfo(g_keyinfo[player][r][c].norm, with_hashcode);
+         print_keyinfo(g_keyinfo[player][r][c].flipV, with_hashcode);
+         print_keyinfo(g_keyinfo[player][r][c].flipH, with_hashcode);
+         print_keyinfo(g_keyinfo[player][r][c].flipVH, with_hashcode);
+         putchar('\n');
+       }
+     }
+ }
+ 
+ 
+ extern void
+ print_external()
+ {
+   //  print_keyinfo_table(HORIZONTAL, 1);
+   print_keyinfo_table(VERTICAL, 1);
+ }
+ 
+ extern s32bit g_print;
+ 
+ extern void
+ print_current_state()
+ {
+   print_board(HORIZONTAL);
+   printf("\n");
+   print_board_info(HORIZONTAL);
+   g_print = 0;
+ }
+ 
+ 
+ extern const char*
+ current_search_state()
+ {
+   static char*  str = NULL;
+ 
+   g_print = 1;
+       
+   if(str != NULL) free(str);
+   
+   asprintf(&str, "Nodes: %s.\n%d %d %d %d %d %d %d %d %d.",
+            u64bit_to_string(g_num_nodes),
+            g_move_number[1], g_move_number[2], g_move_number[3],
+            g_move_number[4], g_move_number[5], g_move_number[6],
+            g_move_number[7], g_move_number[8], g_move_number[9]);
+ 
+   return str;
+ }


Index: llvm/test/Programs/MultiSource/Applications/obsequi/does_x_win.c
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/does_x_win.c:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/does_x_win.c	Tue May 11 14:34:12 2004
***************
*** 0 ****
--- 1,641 ----
+ 
+ #include "globals.h"
+ 
+ #define PRINT_DOES_X_WIN_INFO
+ 
+ // If defined we just immediately return from each function with
+ //   a value of -1. (In other words no winner yet.)
+ //#define NOTHING
+ 
+ // If defined don't pack any protected moves onto the board.
+ //#define NO_PROT
+ 
+ // If defined pretend all (unpacked) squares are available to opponent.
+ //#define NO_UNUSED
+ 
+ // If defined pretend we didn't find any vulnerable moves with a prot square.
+ //#define NO_VULN_W_PROT
+ 
+ // If defined pretend we didn't find any vulnerable moves with a prot square.
+ //#define NO_VULN_TYPE_1
+ 
+ // If defined pretend there were no vulnerable moves (note this also
+ //    means NO_VULN_W_PROT).
+ //#define NO_VULN
+ 
+ // If defined don't look for safe options.
+ //#define NO_SAFE_OPT
+ 
+ //#################################################################
+ // This function tries to pack as many 'protective' areas onto
+ //  the board as it can. (no guarantee of optimality).
+ //#################################################################
+ static inline void
+ pack_prot(u32bit tmp_board[32], s32bit player, s32bit *prot)
+ {
+   s32bit r = 0, p = 0; //row, and number of prot. areas we have placed.
+   
+   u32bit tmp, inter, walls;
+   
+   for(r = 0; r < g_board_size[player]; r++){
+     // set bit at each position where there is interference.
+     inter = (tmp_board[r] | tmp_board[r+1] | tmp_board[r+2] | tmp_board[r+3]
+              | g_board[player][r+1] | g_board[player][r+2]);
+     inter = (inter >> 1) | inter; 
+     
+     // set bit at each position which there is a wall.
+     walls = ( ((g_board[player][r] >> 1) & g_board[player][r])
+               | ((g_board[player][r+3] >> 1) & g_board[player][r+3]) );
+     
+     // combine (bit set at each position which we can place a prot. area).
+     inter = walls & ~inter;
+     
+     // process the positions.
+     while(inter){
+       tmp = (inter & -inter);        // least sig bit of m
+       inter &= ~(tmp | (tmp << 1));  // remove bit and next bit.
+ 
+       tmp_board[r+1] |= tmp | (tmp << 1); //record where we put
+       tmp_board[r+2] |= tmp | (tmp << 1); // the protective square.
+ 
+       p++; // count it.
+     }
+   }
+   
+   *prot = p;
+ }
+ 
+ 
+ //#################################################################
+ // This function tries to pack as many 'vuln. type 1 and 2' areas
+ //  onto the board as it can. (no guarantee of optimality).
+ // It also counts the number of unused squares.
+ //#################################################################
+ static void
+ pack_vuln(u32bit tmp_board[32], s32bit player,
+           s32bit *vuln2, s32bit *vuln2_w_prot,
+           s32bit *vuln1, s32bit *vuln1_w_prot,
+           s32bit *unused) //, s32bit print)
+ {
+   u32bit curr_row, adj_rows, next_prev_row;
+   u32bit tmp = 0, tmp_;
+ 
+   s32bit v2 = 0, v2_p = 0, v1 = 0, v1_p = 0, u = 0;
+   
+   s32bit r, state;
+   u32bit s_v = 0; //start of vulnerable
+   
+   for(r = 0; r < g_board_size[player]; r++){
+     next_prev_row  = tmp_board[r];
+     next_prev_row |= ~(g_board[player][r+2] | (g_board[player][r+2] << 1));
+     next_prev_row |= ~(g_board[player][r+2] | (g_board[player][r+2] >> 1));
+ 
+     curr_row = ~(g_board[player][r+1] | tmp_board[r+1]);
+     adj_rows = g_board[player][r] & g_board[player][r+2];
+     state = 0;
+     
+     //========================================================
+     // Three types of squares, prot, empty, occ.
+     //
+     // state = 0
+     // if(prot)  -> state = 1
+     // if(empty) -> state = 2, c_t = c,
+     // if(occ)   -> state = 0
+     //
+     // state = 1
+     // if(prot)  -> state = 0, safe++
+     // if(empty) -> state = 0, v_p++, mark(c-1)
+     // if(occ)   -> state = 0, unu++
+     //
+     // state = 2
+     // if(prot)  -> state = 3,
+     // if(empty) -> state = 0, vuln++, mark(c_t)
+     // if(occ)   -> state = 0,
+     //
+     // state = 3
+     // if(prot)  -> state = 4, safe++
+     // if(empty) -> state = 2, v_p++, mark(c_t), c_t = c
+     // if(occ)   -> state = 0, v_p++, mark(c_t)
+     //
+     // state = 4
+     // if(prot)  -> state = 3
+     // if(empty) -> state = 2, c_t = c
+     // if(occ)   -> state = 0
+     //========================================================
+ 
+     while(curr_row){
+       tmp_ = (curr_row & -curr_row);  //get least sig bit of curr_row
+       curr_row ^= tmp_;               //remove least sig bit of curr_row.
+ 
+       // if true then this iteration and last iteration are not contiguous.
+       // Which means there was an occupied square.
+       if ( ((tmp_ >> 1) & tmp) == 0 ) {
+         if(state == 1) {
+           u++;
+           tmp_board[r+1] |= tmp;
+         } else if(state == 3) {
+           tmp_board[r+1] |= (s_v | (s_v << 1));
+           if((s_v & next_prev_row) || ((s_v << 1) & next_prev_row))
+             v2_p++;
+           else
+             v1_p++;
+         }
+         state = 0;
+       }
+       tmp = tmp_;
+       
+       // empty and protected
+       if( tmp & adj_rows ){
+         if(state == 0) {
+           state = 1;
+         } else if(state == 1) {
+           state = 0;
+           //safe
+         } else if(state == 2) {
+           state = 3;
+         } else if(state == 3) {
+           state = 4;
+           //safe
+         } else if(state == 4) {
+           state = 3;
+         }
+       }
+       
+       // unprotected
+       else {
+         if(state == 0) {
+           state = 2;
+           s_v = tmp;
+         } else if(state == 1){
+           state = 0;
+ 
+           // Check tmp >> 1
+ 
+           tmp_board[r+1] |= (tmp | (tmp >> 1));
+           if((tmp & next_prev_row) || ((tmp >> 1) & next_prev_row))
+             v2_p++;
+           else
+             v1_p++;
+         } else if(state == 2){
+           state = 0;
+           tmp_board[r+1] |= (s_v | (s_v << 1));
+           if((s_v & next_prev_row) || ((s_v << 1) & next_prev_row))
+             v2++;
+           else
+             v1++;
+         } else if(state == 3){
+           state = 2;
+           tmp_board[r+1] |= (s_v | (s_v << 1));
+           if((s_v & next_prev_row) || ((s_v << 1) & next_prev_row))
+             v2_p++;
+           else
+             v1_p++;
+           s_v = tmp;
+         } else if(state == 4){
+           state = 2;
+           s_v = tmp;
+         }
+       }
+     }
+ 
+     if(state == 1) {
+       u++;
+       tmp_board[r+1] |= tmp;
+     } else if(state == 3) {
+       tmp_board[r+1] |= (s_v | (s_v << 1));
+       if((s_v & next_prev_row) || ((s_v << 1) & next_prev_row))
+         v2_p++;
+       else
+         v1_p++;
+     }
+ 
+     //    if(print)
+     //  printf("%d %d %d %d %d - %X\n", v2, v2_p, v1, v1_p, u,
+     //        tmp_board[r+1]);
+     
+   }
+   //  if(print) printf("\n");
+ 
+   *vuln2 = v2 + v2_p;
+   *vuln2_w_prot = v2_p;
+   *vuln1 = v1 + v1_p;
+   *vuln1_w_prot = v1_p;
+   *unused = u;
+ }
+ 
+ 
+ //#################################################################
+ // This function tries to pack as many 'option of vulnerability' areas
+ //  onto the board as it can. (no guarantee of optimality).
+ //#################################################################
+ static inline void
+ pack_safe(u32bit tmp_board[32], s32bit player,
+           s32bit *safe_op2, s32bit *safe_op1, s32bit *safe_op0)
+ {
+   u32bit guard, mask, curr, tmp;
+ 
+   s32bit r;                       //row
+   s32bit s2 = 0, s1 = 0, s0 = 0;
+   
+   for(r = 0; r < g_board_size[player]; r++){
+     guard = g_board[player][r] & g_board[player][r+2];
+     curr  = g_board[player][r+1] | tmp_board[r+1];
+     
+     // mask contains a bit for each safe move.
+     mask  = ( (~(curr | (curr >> 1))) & (guard & (guard >> 1)) );
+ 
+     while(mask){
+       tmp   =  (mask & -mask);          // least sig bit of m
+       mask &= ~(tmp | (tmp << 1));      // remove bit and next bit.
+ 
+       // add these bits to current.
+       curr |= (tmp | (tmp << 1));
+ 
+       if( ! ( (curr | tmp_board[r] | tmp_board[r+2]) & (tmp >> 1) ) ){
+         // we have an option to move vulnerably. (which option is it).
+         curr           |= (tmp >> 1);
+         tmp_board[r+1] |= (tmp >> 1);
+         
+         // check up.
+         if(  (!(g_board[player][r] & (tmp >> 1)))
+              && (g_board[player][r-1] & (tmp >> 1)) ){
+           // up is good now check down.
+           if(  (!(g_board[player][r+2] & (tmp >> 1)))
+                && (g_board[player][r+3] & (tmp >> 1)) ){
+             s2++;
+           } else {
+             s1++;
+           }
+         } else if(  (!(g_board[player][r+2] & (tmp >> 1)))
+                     && (g_board[player][r+3] & (tmp >> 1)) ){
+           s1++;
+         } else {
+           s0++;
+         }
+       } else 
+       if( ! ( (mask | curr | tmp_board[r] | tmp_board[r+2]) & (tmp << 2) ) ){
+         // we have an option to move vulnerably. (which option is it).
+         curr           |= (tmp << 2);
+         tmp_board[r+1] |= (tmp << 2);
+         
+         // check up.
+         if(  (!(g_board[player][r] & (tmp << 2)))
+              && (g_board[player][r-1] & (tmp << 2)) ){
+           // up is good now check down.
+           if(  (!(g_board[player][r+2] & (tmp << 2)))
+                && (g_board[player][r+3] & (tmp << 2)) ){
+             s2++;
+           } else {
+             s1++;
+           }
+         } else if(  (!(g_board[player][r+2] & (tmp << 2)))
+                     && (g_board[player][r+3] & (tmp << 2)) ){
+           s1++;
+         } else {
+           s0++;
+         }
+       }
+     }
+     //    if(debug) printf("(%d,%d) ", s0, s1);
+   }
+   //  if(debug) printf("\n");
+ 
+   *safe_op2 = s2;
+   *safe_op1 = s1;
+   *safe_op0 = s0;
+ }
+ 
+ //#################################################################
+ // 
+ //#################################################################
+ extern s32bit
+ #ifdef PRINT_DOES_X_WIN_INFO
+ does_next_player_win(s32bit next_player, s32bit print)
+ #else
+ does_next_player_win(s32bit next_player)
+ #endif
+ {
+   // info we directly get from the board.
+   s32bit prot;   // This is the number of protective regions.
+ 
+   s32bit vuln2;   // Total number of vulnerable moves (includes vuln_w_prot).
+   // Num of vuln moves which contain a square unavailable to the opponent.
+   s32bit vuln2_w_prot;
+   s32bit vuln1;   // Total number of vulnerable moves (includes vuln_w_prot).
+   // Num of vuln moves which contain a square unavailable to the opponent.
+   s32bit vuln1_w_prot;
+ 
+   s32bit safe;   // Number of safe moves horizontal has.
+   // Number of squares unused in our packing and unavailable for opponent.
+   s32bit unused;
+   s32bit empty;  // Number of empty squares on board.
+   s32bit safe_op2, safe_op1, safe_op0; //safe moves with options.
+ 
+   // value we return and other variables.
+   s32bit r_value = 0, i;
+ 
+   // temporary board to store which positions have already been packed.
+   u32bit tmp_board[32];
+ 
+ #ifdef NOTHING
+   return -1;
+ #endif
+   
+   //========================================================  
+   // Initialize all of the values.
+   //========================================================  
+   for(i = 0; i < 32; i++) tmp_board[i] = 0;
+   safe  = g_info_totals[next_player].safe;
+   empty = g_empty_squares;
+   
+   // Determine the number of protective regions that we have.
+ #ifdef NO_PROT
+   prot = 0;
+ #else
+   pack_prot(tmp_board, next_player, &prot);
+ #endif
+ 
+   // Determine the number of vuln, vuln_w_prot, and unused.
+   pack_vuln(tmp_board, next_player, &vuln2, &vuln2_w_prot,
+             &vuln1, &vuln1_w_prot, &unused); //, print);
+ 
+ #ifdef NO_VULN_W_PROT
+   vuln1_w_prot = vuln2_w_prot = 0;
+ #endif
+ 
+ #ifdef NO_VULN_TYPE_1
+   vuln2 += vuln1;
+   vuln2_w_prot += vuln1_w_prot;
+   vuln1 = vuln1_w_prot = 0;
+ #endif
+ 
+ #ifdef NO_UNUSED
+   unused = 0;
+ #endif
+ 
+ #ifdef NO_VULN
+   vuln2 = vuln1 = vuln2_w_prot = vuln1_w_prot = 0;
+ #endif
+ 
+   // Determine the number of safe moves with options we have.
+ #ifdef NO_SAFE_OPT
+   safe_op2 = safe_op1 = safe_op0 = 0;
+ #else
+   pack_safe(tmp_board, next_player, &safe_op2, &safe_op1, &safe_op0);
+ #endif
+ 
+ #ifdef PRINT_DOES_X_WIN_INFO
+   if(print){
+     fprintf(stderr, "%d moves next, do they win?\n", next_player);
+     fprintf(stderr, "prot %d, vuln2 %d(%d), vuln1 %d(%d), "
+             "safe %d, unused %d, empty %d.\n",
+             prot, vuln2, vuln2_w_prot, vuln1, vuln1_w_prot,
+             safe, unused, empty);
+     fprintf(stderr, "safe_op2 %d, safe_op1 %d, safe_op0 %d.\n",
+             safe_op2, safe_op1, safe_op0);
+   }
+ #endif
+   
+   {
+     s32bit moves, opp_moves, x = 0;
+ 
+     if(prot % 2 == 1){
+       prot--;
+       safe += 2;
+     } else if(vuln2 % 3 != 0){
+       vuln2--;
+       safe++;
+       if(vuln2_w_prot > vuln2) vuln2_w_prot--;
+     } else if(vuln1 % 2 != 0){
+       vuln1--;
+       safe++;
+       if(vuln1_w_prot > vuln1) vuln1_w_prot--;
+     } else if(safe_op2 % 2 != 0){
+       safe_op2--;
+       unused+=3;
+     } else if(safe_op1 % 2 != 0){
+       safe_op1--;
+       unused+=2;
+     } else if(safe_op0 % 2 != 0){
+       safe_op0--;
+       unused+=1;
+     } else if(vuln2 > 0){
+       vuln2--;
+       safe++;
+       if(vuln2_w_prot > vuln2) vuln2_w_prot--;
+     } else if(vuln1 > 0){
+       vuln1--;
+       safe++;
+       if(vuln1_w_prot > vuln1) vuln1_w_prot--;
+     } else if(prot > 0){
+       prot--;
+       safe += 2;
+     } else {
+       return -1;
+     }
+ 
+     if(prot % 2 == 1){
+       prot--;
+       vuln2 += 2;
+     }
+ 
+     moves = (prot) + (vuln2/3) + (vuln1/2) + safe;
+     
+     if(vuln2 % 3 != 0 && vuln1 % 2 != 0){
+       moves++, unused--, x=1;
+       //      if(vuln2 > 0 || vuln1 > 0) unused--;
+     } else if(vuln2 % 3 == 0 && vuln1 % 2 == 0) x=1;
+ 
+     if(x == 1){
+       if(safe_op2%2 == 1) safe_op2--, safe_op1++;
+       if(safe_op1%2 == 1) safe_op1--, safe_op0++;
+     } else {
+       if(safe_op2%2 == 1){
+         unused += 3;
+         if(safe_op1%2==1) safe_op1--, safe_op0++;
+       } else if(safe_op1%2 == 1) { unused += 2; }
+       else if(safe_op0%2 == 1)   { unused += 1; }
+     }
+     
+     unused += vuln2_w_prot - ( (vuln2)/3 - (vuln2-vuln2_w_prot)/3 );
+     unused += vuln1_w_prot - ( (vuln1)/2 - (vuln1-vuln1_w_prot)/2 );
+ 
+     unused += (safe_op2/2) * 3;
+     unused += (safe_op1/2) * 2;
+     unused += (safe_op0/2) * 1;
+ 
+     opp_moves = (empty - (moves*2) - unused)/2;
+ 
+     //========================================================
+     // If r_value > 0 then next_player wins.
+     //========================================================
+     r_value = moves - opp_moves;
+ 
+ #ifdef PRINT_DOES_X_WIN_INFO
+     if(print){
+       printf("moves:%d, opp:%d.\n", moves, opp_moves);
+       if(moves - opp_moves >= 0) printf("H WINS\n");
+     }
+ #endif
+   }
+ 
+   return r_value;
+ }
+ 
+ 
+ //#################################################################
+ // 
+ //#################################################################
+ extern s32bit
+ #ifdef PRINT_DOES_X_WIN_INFO
+ does_who_just_moved_win(s32bit who_just_moved, s32bit print)
+ #else
+ does_who_just_moved_win(s32bit who_just_moved)
+ #endif
+ {
+   // info we directly get from the board.
+   s32bit prot;   // This is the number of protective regions.
+ 
+   s32bit vuln2;   // Total number of vulnerable moves (includes vuln_w_prot).
+   // Num of vuln moves which contain a square unavailable to the opponent.
+   s32bit vuln2_w_prot;
+   s32bit vuln1;   // Total number of vulnerable moves (includes vuln_w_prot).
+   // Num of vuln moves which contain a square unavailable to the opponent.
+   s32bit vuln1_w_prot;
+ 
+   s32bit safe;   // Number of safe moves horizontal has.
+   // Number of squares unused in our packing and unavailable for opponent.
+   s32bit unused;
+   s32bit empty;  // Number of empty squares on board.
+   s32bit safe_op2, safe_op1, safe_op0; //safe moves with options.
+ 
+   // value we return and other variables.
+   s32bit r_value = 0, i;
+ 
+   // temporary board to store which positions have already been packed.
+   u32bit tmp_board[32];
+   
+ #ifdef NOTHING
+   return -1;
+ #endif
+   
+   //========================================================  
+   // Initialize all of the values.
+   //========================================================  
+   for(i = 0; i < 32; i++) tmp_board[i] = 0;
+   safe  = g_info_totals[who_just_moved].safe;
+   empty = g_empty_squares;
+   
+   // Determine the number of protective regions that we have.
+ #ifdef NO_PROT
+   prot = 0;
+ #else
+   pack_prot(tmp_board, who_just_moved, &prot);
+ #endif
+ 
+   // Determine the number of vuln, vuln_w_prot, and unused.
+   pack_vuln(tmp_board, who_just_moved, &vuln2, &vuln2_w_prot,
+             &vuln1, &vuln1_w_prot, &unused);
+ 
+ #ifdef NO_VULN_W_PROT
+   vuln1_w_prot = vuln2_w_prot = 0;
+ #endif
+ 
+ #ifdef NO_VULN_TYPE_1
+   vuln2 += vuln1;
+   vuln2_w_prot += vuln1_w_prot;
+   vuln1 = vuln1_w_prot = 0;
+ #endif
+ 
+ #ifdef NO_UNUSED
+   unused = 0;
+ #endif
+ 
+ #ifdef NO_VULN
+   vuln2 = vuln1 = vuln2_w_prot = vuln1_w_prot = 0;
+ #endif
+ 
+   // Determine the number of safe moves with options we have.
+ #ifdef NO_SAFE_OPT
+   safe_op2 = safe_op1 = safe_op0 = 0;
+ #else
+   pack_safe(tmp_board, who_just_moved, &safe_op2, &safe_op1, &safe_op0);
+ #endif
+   
+   /*
+   if(prot % 2 == 1){
+     prot--;
+     vuln2 += 2;
+   }
+ 
+   if(print == 1 && unused > 0
+      && prot >= 2 // && (vuln2%3 != 0 || vuln1%2 != 0)
+      && vuln2 >= 3 && vuln1 >= 2
+      && safe_op1 + safe_op0 >= 2){
+     print_board(who_just_moved);
+   } else {
+     print = 0;
+   }
+   */
+ #ifdef PRINT_DOES_X_WIN_INFO
+   if(print){
+     fprintf(stderr, "%d just moved, do they win?\n", who_just_moved);
+     fprintf(stderr, "prot %d, vuln2 %d(%d), vuln1 %d(%d), "
+             "safe %d, unused %d, empty %d.\n",
+             prot, vuln2, vuln2_w_prot, vuln1, vuln1_w_prot,
+             safe, unused, empty);
+     fprintf(stderr, "safe_op2 %d, safe_op1 %d, safe_op0 %d.\n",
+             safe_op2, safe_op1, safe_op0);
+   }
+ #endif
+   
+   {
+     s32bit moves, opp_moves, x = 0;
+ 
+     if(prot % 2 == 1){
+       prot--;
+       vuln2 += 2;
+     }
+     
+     moves = (prot) + (vuln2/3) + (vuln1/2) + safe;
+     
+     if(vuln2 % 3 != 0 && vuln1 % 2 != 0){
+       moves++, unused--, x=1;
+       //      if(vuln2 > 0 || vuln1 > 0) unused--;
+     } else if(vuln2 % 3 == 0 && vuln1 % 2 == 0) x=1;
+ 
+     if(x == 1){
+       if(safe_op2%2 == 1) safe_op2--, safe_op1++;
+       if(safe_op1%2 == 1) safe_op1--, safe_op0++;
+     } else {
+       if(safe_op2%2 == 1){
+         unused += 3;
+         if(safe_op1%2==1) safe_op1--, safe_op0++;
+       } else if(safe_op1%2 == 1) { unused += 2; }
+       else if(safe_op0%2 == 1)   { unused += 1; }
+     }
+     
+     unused += vuln2_w_prot - ( (vuln2)/3 - (vuln2-vuln2_w_prot)/3 );
+     unused += vuln1_w_prot - ( (vuln1)/2 - (vuln1-vuln1_w_prot)/2 );
+ 
+     unused += (safe_op2/2) * 3;
+     unused += (safe_op1/2) * 2;
+     unused += (safe_op0/2) * 1;
+ 
+     opp_moves = (empty - (moves*2) - unused)/2;
+ 
+     //========================================================
+     // If r_value >= 0 then who_just_moved wins.
+     //========================================================
+     r_value = moves - opp_moves;
+ 
+ #ifdef PRINT_DOES_X_WIN_INFO
+     if(print){
+       printf("moves:%d, opp:%d.\n", moves, opp_moves);
+       if(moves - opp_moves >= 0) printf("H WINS\n");
+     }
+ #endif
+   }
+ 
+   return r_value;
+ }


Index: llvm/test/Programs/MultiSource/Applications/obsequi/globals.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/globals.h:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/globals.h	Tue May 11 14:34:12 2004
***************
*** 0 ****
--- 1,224 ----
+ 
+ #ifndef GLOBALS_H
+ #define GLOBALS_H
+ 
+ #include "utils.h"
+ 
+ #include "interface.h"
+ 
+ #include "structs.h"
+ #include "consts.h"
+ 
+ 
+ //########################################################
+ // Function prototypes.
+ //########################################################
+ 
+ //========================================================
+ // Generate a list of moves that 'player'
+ //   can make in the given position. (excluding safe moves).
+ //
+ // The moves are places in the movelist array.
+ // Returns the number of moves that were placed in movelist.
+ //========================================================
+ s32bit  move_generator        (Move movelist[MAXMOVES], s32bit player);
+ 
+ s32bit  move_generator_stage1 (Move movelist[MAXMOVES], s32bit player);
+ 
+ s32bit  move_generator_stage2 (Move movelist[MAXMOVES],
+                                s32bit start, s32bit player);
+ 
+ //=================================================================
+ // Move ordering uses a simple evaluation function as well as
+ //   a value associated with each position.
+ // The first two function set these values in a dynamic way.
+ // The 'set_position_values' function does it statically.
+ //=================================================================
+ #ifdef DYNAMIC_POSITION_VALUES
+ void    init_move_value     ();
+ s32bit  set_move_value      (Move movelist, s32bit player);
+ void    unset_move_value    (Move movelist, s32bit player);
+ #else
+ void    set_position_values ();
+ #endif
+ 
+ //========================================================
+ // Toggle a move, if a move hasn't been played then play it, if
+ //   it has then undo it.
+ //========================================================
+ void    toggle_move    (Move move, s32bit player);
+ 
+ //========================================================
+ // Give score of move relative to current position.
+ //========================================================
+ //s32bit  score_move(Move move, s32bit player);
+ void
+ score_and_get_first(Move movelist[MAXMOVES], s32bit num_moves,
+                     s32bit player, Move first);
+ 
+ //========================================================
+ // Use the value of movelist[i].info to sort the moves in
+ //   descending order.
+ //========================================================
+ void    sort_moves(Move movelist[MAXMOVES], s32bit start, s32bit num_moves);
+ 
+ 
+ void
+ update_safe(s32bit player, s32bit row);
+ 
+ void
+ update_real(s32bit player, s32bit row);
+ 
+ 
+ void init_less_static_tables();
+ 
+ 
+ void init_static_tables();
+ 
+ 
+ 
+ // make the bitboard consistent with the info past into this function.
+ void    init__board(s32bit num_rows, s32bit num_cols, s32bit board[30][30]);
+ 
+ void    initialize_tables();
+ 
+ 
+ 
+ //########################################################
+ // Functions for interacting with the hashtable.
+ //========================================================
+ // Store the current search value into the hashtable if there
+ //   is a position available.
+ //========================================================
+ void    hashstore      (s32bit value, s32bit alpha, s32bit beta,
+                         u32bit nodes, s32bit depth_remaining,
+                         Move best, s32bit player);
+ 
+ 
+ //========================================================
+ // Check the hashtable to see if we have already seen the current
+ //   position before.
+ //========================================================
+ s32bit  hashlookup     (s32bit *value, s32bit *alpha, s32bit *beta,
+                         s32bit depth_remaining,
+                         Move *force_first, s32bit player);
+ 
+ 
+ //########################################################
+ // Functions for information display or sanity checks.
+ //========================================================
+ // Functions which varify pieces of information.
+ //========================================================
+ void    check_board();
+ void    check_board_info();
+ 
+ void    check_hash_code_sanity();
+ 
+ 
+ //========================================================
+ // Functions which print various pieces of information in a
+ //   readable format.
+ //========================================================
+ void    print_board(s32bit player);
+ void    print_board_info();
+ void    print_bitboard(s32bit player);
+ void    print_hashkey(Hash_Key key);
+ void    print_u64bit(u64bit val);
+ void    print_hashentry(s32bit index);
+ 
+ 
+ 
+ //########################################################
+ // Global variables.
+ //########################################################
+ 
+ extern u64bit       g_num_nodes;
+ 
+ 
+ // two bitboard arrays [0] is horizontals, [1] is verticals.
+ extern u32bit       g_board[2][32];
+ 
+ // number of rows and cols in the board.
+ // [0] is the num of rows, [1] is the num of cols.
+ extern s32bit       g_board_size[2];
+ 
+ // keep track of simple info such as real and safe moves.
+ extern Basic_Info   g_info[2][32];
+ extern Basic_Info   g_info_totals[2];
+ extern s32bit       g_empty_squares;
+ 
+ // zobrist value for each position on the board.
+ extern s32bit       g_zobrist[32][32];
+ 
+ // Transposition table.
+ extern Hash_Entry  *g_trans_table;
+ 
+ // Current boards hash key and code (flipped in various ways).
+ extern Hash_Key     g_norm_hashkey;
+ extern Hash_Key     g_flipV_hashkey;
+ extern Hash_Key     g_flipH_hashkey;
+ extern Hash_Key     g_flipVH_hashkey;
+ 
+ extern s32bit       g_first_move[2][32][32];
+ 
+ extern s32bit       g_move_number[128];
+ 
+ 
+ 
+ //########################################################
+ // Tables of precalculated information.
+ //
+ // Calling initialize_board should initialize the information in
+ //   all these tables.
+ //########################################################
+ 
+ 
+ //========================================================
+ // Declare the table we use for updating our hashkey after each move.
+ //========================================================
+ extern KeyInfo      g_keyinfo[2][32][32];
+ 
+ 
+ //========================================================
+ // Declare the table we use in countmoves.
+ //========================================================
+ #ifdef COUNTMOVES_TABLE
+ extern s32bit move_table16[65536];
+ #endif
+ 
+ 
+ //========================================================
+ // Declare the table we use in countbits32.
+ //========================================================
+ #if defined COUNTBITS16
+ extern s32bit countbits16[65536];
+ 
+ #if defined COUNTBITS8
+ #error "Both COUNTBITS8 and COUNTBITS16 are defined."
+ #endif
+ 
+ #elif defined COUNTBITS8
+ extern s32bit countbits8[256];
+ #else
+ #error "Neither COUNTBITS8 or COUNTBITS16 are defined."
+ #endif
+ 
+ 
+ //========================================================
+ // Declare the table we use in lastbit32.
+ //========================================================
+ #if defined LASTBIT16
+ extern s32bit lastbit16[65536];
+ 
+ #if defined LASTBIT8
+ #error "Both LASTBIT8 and LASTBIT16 are defined."
+ #endif
+ 
+ #elif defined LASTBIT8
+ extern s32bit lastbit8[256];
+ #else
+ #error "Neither LASTBIT8 and LASTBIT16 are defined."
+ #endif
+ 
+ 
+ #endif //ifndef GLOBALS_H


Index: llvm/test/Programs/MultiSource/Applications/obsequi/hash.c
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/hash.c:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/hash.c	Tue May 11 14:34:12 2004
***************
*** 0 ****
--- 1,109 ----
+ 
+ #include "globals.h"
+ 
+ #define MOVE_TO_INT(mv, player)   \
+    ((mv).mask_index-1)*g_board_size[(player)]+((mv).array_index-1)
+ 
+ #define TABLE_SET_KEY(table,index,k)                          \
+    table[index].key[0] = k[0], table[index].key[1] = k[1],    \
+    table[index].key[2] = k[2], table[index].key[3] = k[3]; 
+ 
+ #define TABLE_CMP_KEY(table,index,k)                              \
+    (table[index].key[0] == k[0] && table[index].key[1] == k[1] && \
+     table[index].key[2] == k[2] && table[index].key[3] == k[3]) 
+ 
+ 
+ #define STORE_ENTRY(x)                                          \
+   index = (x).code;                                             \
+                                                                 \
+   if(TABLE_CMP_KEY(g_trans_table, index, (x).key)               \
+      || g_trans_table[index].nodes <= nodes){                   \
+     TABLE_SET_KEY(g_trans_table, index, (x).key);               \
+     g_trans_table[index].nodes     =nodes;                      \
+     g_trans_table[index].best_move =MOVE_TO_INT(best,player);   \
+     g_trans_table[index].depth     =depth;                      \
+     g_trans_table[index].whos_turn =player;                     \
+     g_trans_table[index].value     =value;                      \
+     if     (value>=beta) g_trans_table[index].type =LOWER;      \
+     else if(value>alpha) g_trans_table[index].type =EXACT;      \
+     else                 g_trans_table[index].type =UPPER;      \
+     return;                                                     \
+   }
+ 
+ 
+ extern void
+ hashstore(s32bit value, s32bit alpha, s32bit beta,
+           u32bit nodes, s32bit depth, Move best, s32bit player)
+ {
+   s32bit index;
+ 
+   STORE_ENTRY(g_norm_hashkey);
+   STORE_ENTRY(g_flipV_hashkey);
+   STORE_ENTRY(g_flipH_hashkey);
+   STORE_ENTRY(g_flipVH_hashkey);
+ }
+ 
+ 
+ #define INT_TO_MOVE(mv, int, player)                    \
+    (mv).mask_index = ((int)/g_board_size[(player)])+1;  \
+    (mv).array_index = ((int)%g_board_size[(player)])+1
+ 
+ #define LOOKUP_ENTRY(x)                                                 \
+   index = (x).code;                                                     \
+   if(TABLE_CMP_KEY(g_trans_table, index, (x).key)                       \
+      && g_trans_table[index].whos_turn == player ) {                    \
+     /* found matching entry.*/                                          \
+                                                                         \
+     /* If nothing else we can use this entry to give us a good move. */ \
+     INT_TO_MOVE(*force_first, g_trans_table[index].best_move, player);  \
+                                                                         \
+     /* use value if depth >= than the depth remaining in our search. */    \
+     if(g_trans_table[index].depth >= depth_remaining) {                 \
+                                                                         \
+       /* if the value is exact we can use it. */                          \
+       if(g_trans_table[index].type == EXACT) {                          \
+         *value=g_trans_table[index].value;                              \
+         return 1;                                                       \
+       }                                                                 \
+                                                                         \
+       /* if value is a lower bound we can possibly use it. */             \
+       if(g_trans_table[index].type == LOWER) {                          \
+         if(g_trans_table[index].value>=(*beta)){                        \
+           *value=g_trans_table[index].value;                            \
+           return 1;                                                     \
+         }                                                               \
+         if(g_trans_table[index].value>(*alpha)){                        \
+           *alpha=g_trans_table[index].value;                            \
+         }                                                               \
+         return 0;                                                       \
+       }                                                                 \
+                                                                         \
+       /* if value is a upper bound we can possibly use it. */             \
+       if(g_trans_table[index].type == UPPER) {                          \
+         if(g_trans_table[index].value<=(*alpha)){                       \
+           *value=g_trans_table[index].value;                            \
+           return 1;                                                     \
+         }                                                               \
+         if(g_trans_table[index].value<(*beta)){                         \
+           *beta=g_trans_table[index].value;                             \
+         }                                                               \
+         return 0;                                                       \
+       }                                                                 \
+     }                                                                   \
+   }
+ 
+ 
+ 
+ extern s32bit
+ hashlookup(s32bit *value, s32bit *alpha, s32bit *beta,
+            s32bit depth_remaining, Move *force_first, s32bit player)
+ {
+   s32bit index;
+   
+   LOOKUP_ENTRY(g_norm_hashkey);
+   LOOKUP_ENTRY(g_flipV_hashkey);
+   LOOKUP_ENTRY(g_flipH_hashkey);
+   LOOKUP_ENTRY(g_flipVH_hashkey);
+ 
+   return 0;
+ }


Index: llvm/test/Programs/MultiSource/Applications/obsequi/init.c
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/init.c:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/init.c	Tue May 11 14:34:12 2004
***************
*** 0 ****
--- 1,172 ----
+ 
+ #include "globals.h"
+ 
+ 
+ u32bit     g_board[2][32];
+ s32bit     g_board_size[2] = {-1,-1};
+ 
+ Basic_Info g_info[2][32];
+ Basic_Info g_info_totals[2];
+ 
+ // zobrist value for each position on the board.
+ s32bit       g_zobrist[32][32];
+ 
+ // Transposition table.
+ Hash_Entry  *g_trans_table = 0;
+ 
+ // Current boards hash key and code (flipped in various ways).
+ Hash_Key     norm_hashkey;
+ Hash_Key     flipV_hashkey;
+ Hash_Key     flipH_hashkey;
+ Hash_Key     flipVH_hashkey;
+ 
+ 
+ extern void
+ init__safe_count(s32bit player)
+ {
+   s32bit i;
+     
+   g_info_totals[player].safe = 0;
+ 
+   for(i = 0; i < g_board_size[player]; i++){
+     g_info[player][i+1].safe = 0;
+     
+     update_safe(player, i+1);
+   }
+ }
+ 
+ extern void
+ init__real_count(s32bit player)
+ {
+   s32bit i;
+     
+   g_info_totals[player].real = 0;
+ 
+   for(i = 0; i < g_board_size[player]; i++){
+     g_info[player][i+1].real = 0;
+     
+     update_real(player, i+1);
+   }
+ }
+ 
+ extern void
+ initialize_solver()
+ {
+   s32bit i, j;
+ 
+   if(g_trans_table == NULL){
+ 
+     // first time initialization stuff.
+     g_trans_table = malloc(HASHSIZE*sizeof(Hash_Entry));
+   
+     // initialize zobrist values
+     srandom(1);
+     for(i=1; i<31; i++) {
+       for(j=1; j<31; j++) {
+         g_zobrist[i][j] = random() & HASHMASK;
+       }
+     }
+ 
+     init_static_tables();
+   }
+ 
+   init_less_static_tables();
+ }
+ 
+ 
+ 
+ static void
+ init_hashkey_code(Hash_Key* key)
+ {
+   s32bit i, j, index, n_rows, n_cols;
+   
+   n_rows = g_board_size[HORIZONTAL], n_cols = g_board_size[VERTICAL];
+ 
+   key->code = 0;
+   
+   for(i = 0; i < n_rows; i++)
+     for(j = 0; j < n_cols; j++){
+       index = (i*n_cols) + j;
+       if(key->key[index/32] & NTH_BIT(index%32))
+         key->code ^= g_zobrist[i+1][j+1];
+     }
+ }
+ 
+ extern void
+ initialize_board(s32bit num_rows, s32bit num_cols, s32bit board[30][30])
+ {
+   s32bit i, j;
+   s32bit init = 0;
+   
+   if(num_rows > 30 || num_rows < 1 || num_cols > 30 || num_cols < 1)
+     fatal_error(1, "Invalid board size %dX%d.\n", num_rows, num_cols);
+ 
+   if(num_rows * num_cols >= 128)
+     fatal_error(1, "Invalid board size %dX%d.\n", num_rows, num_cols);
+   
+   // Check if we need to re-initialize the solver.
+   if(g_trans_table == NULL || g_board_size[HORIZONTAL] != num_rows
+      ||  g_board_size[VERTICAL] != num_cols) init = 1;
+   
+   g_board_size[HORIZONTAL] = num_rows;
+   g_board_size[VERTICAL]   = num_cols;
+ 
+   if(init) initialize_solver();
+ 
+   // Fill all positions on the board.
+   for(i = 0; i < 32; i++){
+     g_board[0][i] = ALL_BITS;
+     g_board[1][i] = ALL_BITS;
+   }
+   
+   // Clear positions where there isn't a piece.
+   for(i = 0; i < num_rows; i++)
+     for(j = 0; j < num_cols; j++)
+       if(board[i][j] == 0){
+         g_board[HORIZONTAL][i+1] &= ~(NTH_BIT(j+1));
+         g_board[VERTICAL][j+1]   &= ~(NTH_BIT(i+1));
+       }
+ 
+   init__real_count(VERTICAL);
+   init__real_count(HORIZONTAL);
+ 
+   init__safe_count(VERTICAL);
+   init__safe_count(HORIZONTAL);
+ 
+   for(i = 0; i < 4; i++){
+     g_norm_hashkey.key[i]   = 0;
+     g_flipV_hashkey.key[i]  = 0;
+     g_flipH_hashkey.key[i]  = 0;
+     g_flipVH_hashkey.key[i] = 0;
+   }
+ 
+   // Modify hashkeys to deal with positions which are already occupied.
+   for(i = 0; i < num_rows; i++)
+     for(j = 0; j < num_cols; j++)
+       if(board[i][j] != 0){
+         s32bit index;
+ 
+         index = (i*num_cols)+j;
+         g_norm_hashkey.key[index/32] |= NTH_BIT(index%32);
+         
+         index = (i*num_cols)                  + (num_cols - j - 1);
+         g_flipV_hashkey.key[index/32] |= NTH_BIT(index%32);
+         
+         index = ( (num_rows - i - 1) *num_cols) + j;
+         g_flipH_hashkey.key[index/32] |= NTH_BIT(index%32);
+         
+         index = ( (num_rows - i - 1) *num_cols) + (num_cols - j - 1);
+         g_flipVH_hashkey.key[index/32] |= NTH_BIT(index%32);
+       }
+   
+   init_hashkey_code(&g_norm_hashkey);
+   init_hashkey_code(&g_flipV_hashkey);
+   init_hashkey_code(&g_flipH_hashkey);
+   init_hashkey_code(&g_flipVH_hashkey);
+   
+   print_board(HORIZONTAL);
+   printf("\n");
+   print_board_info(HORIZONTAL);
+ 
+   check_hash_code_sanity();
+ }


Index: llvm/test/Programs/MultiSource/Applications/obsequi/interface.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/interface.h:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/interface.h	Tue May 11 14:34:12 2004
***************
*** 0 ****
--- 1,45 ----
+ 
+ #ifndef OBSEQUI_INTERFACE_H
+ #define OBSEQUI_INTERFACE_H
+ 
+ //########################################################
+ // 
+ //########################################################
+ void   print_external();
+ 
+ //########################################################
+ // This function initializes the solver.
+ //
+ // This includes things like allocating and zeroing data
+ //   for the hashtable.
+ //
+ // If it is called a second time it will re-zero all the
+ //   data, (restart from scratch).
+ //########################################################
+ void   initialize_solver ();
+ 
+ 
+ //########################################################
+ // This function gives the solver the current board that
+ //   we want to work with.
+ //########################################################
+ void   initialize_board  (s32bit row, s32bit col,
+                           s32bit board[30][30]);
+ 
+ 
+ //########################################################
+ // This function tries to find the best move for 'player'.
+ //
+ //  - player is either 'V' or 'H'.
+ //########################################################
+ s32bit search_for_move   (char player,
+                           s32bit *row, s32bit *col, u64bit *nodes);
+ 
+ 
+ //########################################################
+ // This function returns a string about the current
+ //   state of the search.
+ //########################################################
+ const char*  current_search_state();
+ 
+ #endif


Index: llvm/test/Programs/MultiSource/Applications/obsequi/macros.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/macros.h:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/macros.h	Tue May 11 14:34:12 2004
***************
*** 0 ****
--- 1,138 ----
+ 
+ 
+ #ifndef MACROS_H
+ #define MACROS_H
+ 
+ #include "globals.h"
+ 
+ 
+ //########################################################
+ // We use tables to count how many bits are set in a bitmask.
+ //########################################################
+ #ifdef COUNTBITS8
+ #define countbits32(x) (countbits8[x&0x000000FF] \
+                         +countbits8[(x>>8)&0x000000FF]\
+                         +countbits8[(x>>16)&0x000000FF]\
+                         +countbits8[(x>>24)&0x000000FF])
+ #endif
+ 
+ #ifdef COUNTBITS16
+ #define countbits32(x) (countbits16[x&0x0000FFFF] \
+                         +countbits16[(x>>16)&0x0000FFFF])
+ #endif
+ 
+ 
+ //########################################################
+ // Assume we have a mask with only one bit set -
+ //   we use tables to determine the index of this bit.
+ //########################################################
+ static inline u32bit
+ lastbit32(u32bit x)
+ {
+ #ifdef LASTBIT8
+   /* returns the position of the last bit in x */
+   if(x&0x000000FF)
+     return(lastbit8[x&0x000000FF]);
+   if(x&0x0000FF00)
+     return(lastbit8[(x>>8)&0x000000FF]+8);
+   if(x&0x00FF0000)
+     return(lastbit8[(x>>16)&0x000000FF]+16);
+   if(x&0xFF000000)
+     return(lastbit8[(x>>24)&0x000000FF]+24);
+   return 100;
+ #endif
+ 
+ #ifdef LASTBIT16
+   /* returns the position of the last bit in x */
+   if(x&0x0000FFFF)
+     return(lastbit16[x&0x0000FFFF]);
+   if(x&0xFFFF0000)
+     return(lastbit16[(x>>16)&0x0000FFFF]+16);
+   return 100;
+ #endif
+ }
+ 
+ 
+ //########################################################
+ // Define the function COUNTMOVES.
+ //  This is either a macro or an inline function.
+ //########################################################
+ static inline s32bit
+ COUNTMOVES_DYN(u32bit mask)
+ {
+   s32bit count = 0;
+   u32bit tmp;
+   
+   while(mask){
+     tmp = (mask&-mask);           // least sig bit of m
+     mask &= ~(tmp | (tmp << 1));  // remove bit and next bit.
+     count++;
+   }
+   return count;
+ }
+ 
+ #ifdef COUNTMOVES_TABLE
+ #ifdef BOARD_SIZE_LT_16
+ //========================================================
+ // count moves (assuming small board).
+ //========================================================
+ #define COUNTMOVES(mask) move_table16[(mask)]
+ 
+ #else
+ //========================================================
+ // count moves (assuming large board).
+ //========================================================
+ static inline s32bit
+ COUNTMOVES(u32bit mask)
+ {
+   s32bit count = 0;
+   count = move_table16[mask & 0x0000FFFF];
+ 
+   if(count&0xF0000000)
+     count = ((count & 0x0000FFFF) + move_table16[mask >> 16]) & 0x0000FFFE;
+   else
+     count = (count + move_table16[mask >> 16]) & 0x0000FFFF;
+   
+   return count;
+   
+   /*
+   if(count&ERASE_NEXT_BIT) mask &= ~(NEXT_BIT);
+   return (count + move_table16[mask >> 16]) & 0x0000FFFF;
+   */
+ }
+ 
+ #endif
+ #else
+ //========================================================
+ // count moves (move_table doesn't exist).
+ //========================================================
+ #define COUNTMOVES(mask) COUNTMOVES_DYN(mask)
+ 
+ #endif
+ 
+ 
+ 
+ 
+ #define HASHKEY_UPDATE(key,index) key[index/32] ^= NTH_BIT(index%32)
+ 
+ 
+ #define toggle_hash_code(info)  \
+                                                               \
+ HASHKEY_UPDATE(g_norm_hashkey.key, info.norm.bit1_index);     \
+ HASHKEY_UPDATE(g_norm_hashkey.key, info.norm.bit2_index);     \
+ g_norm_hashkey.code ^= info.norm.hash_code;                   \
+                                                               \
+ HASHKEY_UPDATE(g_flipV_hashkey.key, info.flipV.bit1_index);   \
+ HASHKEY_UPDATE(g_flipV_hashkey.key, info.flipV.bit2_index);   \
+ g_flipV_hashkey.code ^= info.flipV.hash_code;                 \
+                                                               \
+ HASHKEY_UPDATE(g_flipH_hashkey.key, info.flipH.bit1_index);   \
+ HASHKEY_UPDATE(g_flipH_hashkey.key, info.flipH.bit2_index);   \
+ g_flipH_hashkey.code ^= info.flipH.hash_code;                 \
+                                                               \
+ HASHKEY_UPDATE(g_flipVH_hashkey.key, info.flipVH.bit1_index); \
+ HASHKEY_UPDATE(g_flipVH_hashkey.key, info.flipVH.bit2_index); \
+ g_flipVH_hashkey.code ^= info.flipVH.hash_code;
+ 
+ 
+ #endif //MACROS_H


Index: llvm/test/Programs/MultiSource/Applications/obsequi/move_gen.c
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/move_gen.c:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/move_gen.c	Tue May 11 14:34:12 2004
***************
*** 0 ****
--- 1,127 ----
+ 
+ #include "globals.h"
+ #include "macros.h"
+ 
+ //#################################################################
+ // The following functions are used to generate all the possible
+ //   moves which could be made, for a certain player, given
+ //   the current board position.
+ //#################################################################
+ 
+ //=================================================================
+ // This function generates all the moves in one pass.
+ //=================================================================
+ extern s32bit
+ move_generator(Move movelist[MAXMOVES], s32bit player)
+ {
+   s32bit i, count = 0, player_index;
+   u32bit prot_rows, curr_row, m, tmp;
+ 
+   // Will be 0 if horizontal, 1 if vertical.
+   // Appears to be redundant but seems to help the compiler optimize.
+   player_index = player&PLAYER_MASK;
+   
+   for(i = 0; i < g_board_size[player_index]; i++){
+     prot_rows = g_board[player_index][i] & g_board[player_index][i+2];
+     curr_row  = g_board[player_index][i+1];
+     
+ #ifndef PLAY_SAFE_MOVES
+     // m contains a 1 at each position where there is valid move.
+     //    (except safe moves, there is no need to play them)
+     m = ~((curr_row|(curr_row>>1)) | (prot_rows&(prot_rows>>1)));
+ #else
+     // if you uncomment this it will also play safe moves.
+     m = ~(curr_row|(curr_row>>1));
+ #endif    
+ 
+     while(m){
+       tmp = (m&-m); // least sig bit of m
+       m  ^= tmp;    // remove least sig bit of m.
+       movelist[count].mask_index  = lastbit32(tmp);
+       movelist[count].array_index = i+1;
+       movelist[count].info        = 0;
+       count++;
+     }
+   }
+   
+   return count;
+ }
+ 
+ //=================================================================
+ // The following functions use a two pass system. This means possibly
+ //   less cost in evaluating (because if we find a cutoff quickly
+ //   we will not have to evaluate the second half) and in sorting the
+ //   moves.
+ //=================================================================
+ extern s32bit
+ move_generator_stage1(Move movelist[MAXMOVES], s32bit player)
+ {
+   s32bit i, count = 0;
+   s32bit player_index;
+   
+   u32bit prot_rows, curr_row, m, tmp;
+ 
+   // will be 0 if horizontal, 1 if vertical.
+   // This appears to be redundant but it seems to helps the compiler
+   //  optimize.
+   player_index = player&PLAYER_MASK;
+   
+   for(i = 0; i < g_board_size[player_index]; i++){
+     prot_rows = g_board[player_index][i] & g_board[player_index][i+2];
+     curr_row  = g_board[player_index][i+1];
+     
+     // m will contain a 1 at each position that there is a move
+     //   which is a vulnerable move with no protected squares.
+     m = ~((curr_row|(curr_row>>1)) | (prot_rows|(prot_rows>>1)));
+     
+     while(m){
+       tmp = (m&-m); // least sig bit of m
+       m ^= tmp;     // remove least sig bit of m.
+       movelist[count].mask_index  = lastbit32(tmp);
+       movelist[count].array_index = i+1;
+       movelist[count].info        = 0;
+       count++;
+     }
+   }
+ 
+   return count;
+ }
+ 
+ extern s32bit
+ move_generator_stage2(Move movelist[MAXMOVES], s32bit count, s32bit player)
+ {
+   s32bit i, player_index;
+   u32bit prot_rows, curr_row, m, tmp;
+ 
+   // will be 0 if horizontal, 1 if vertical.
+   // This appears to be redundant but it seems to helps the compiler
+   //  optimize.
+   player_index = player&PLAYER_MASK;
+   
+   for(i = 0; i < g_board_size[player_index]; i++){
+     prot_rows = g_board[player_index][i] & g_board[player_index][i+2];
+     curr_row  = g_board[player_index][i+1];
+     
+ #ifndef PLAY_SAFE_MOVES
+     // m will contain a 1 at each position that there is a move
+     //   which is a vulnerable move with a protected squares.
+     m = ~((curr_row|(curr_row>>1)) | (~(prot_rows^(prot_rows>>1))) );
+ #else
+     // m will contain a 1 at each position that there is a move
+     //   which is a vulnerable move with a protected squares.
+     m = ((~((curr_row|(curr_row>>1)) | (prot_rows|(prot_rows>>1))))
+          ^ (~(curr_row|(curr_row>>1))));
+ #endif
+     
+     while(m){
+       tmp = (m&-m); // least sig bit of m
+       m ^= tmp;     // remove least sig bit of m.
+       movelist[count].mask_index  = lastbit32(tmp);
+       movelist[count].array_index = i+1;
+       movelist[count].info        = 0;
+       count++;
+     }
+   }
+ 
+   return count;
+ }


Index: llvm/test/Programs/MultiSource/Applications/obsequi/move_sort.c
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/move_sort.c:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/move_sort.c	Tue May 11 14:34:12 2004
***************
*** 0 ****
--- 1,63 ----
+ 
+ #include "globals.h"
+ 
+ //********************************************************
+ // Move sorting function.
+ //
+ // This is where the program spends some of the larger
+ //   portions of its time. Sometime it should be sped up.
+ //********************************************************
+ 
+ #define NUM_BUCKETS 128
+ 
+ //=================================================================
+ // This is a stable sort algorithm (uses a bucket sort algorithm).
+ //=================================================================
+ extern void
+ sort_moves(Move movelist[MAXMOVES], s32bit start, s32bit num_moves)
+ {
+   Move    bucket[NUM_BUCKETS][MAXMOVES];
+   s32bit  buck_val[NUM_BUCKETS];
+   s32bit  buck_size[NUM_BUCKETS];
+ 
+   s32bit num_buckets = 0, i, j;
+   
+   // place each move in it's proper bucket.
+   for(i = start; i < num_moves; i++){
+     for(j = 0; j < num_buckets; j++){
+       if(movelist[i].info == buck_val[j]){
+         bucket[j][buck_size[j]++] = movelist[i];
+         break;
+       }
+     }
+     if(j == num_buckets){
+       if(j == NUM_BUCKETS) fatal_error(1, "Not enough buckets.\n");
+       bucket[j][0] = movelist[i];
+       buck_val[j] = movelist[i].info;
+       buck_size[j] = 1;
+       num_buckets++;
+     }
+   }
+   
+   // remove the moves from their buckets in the proper order.
+   {
+     s32bit best, index, count = start;
+     
+     while(count != num_moves){
+       
+       best = buck_val[0];
+       index = 0;
+       
+       for(i = 1; i < num_buckets; i++)
+         if(buck_val[i] > best) index = i, best = buck_val[i];
+       
+       // every bucket must have at least one move.
+       i = 0;
+       do {
+         movelist[count++] = bucket[index][i++];
+       } while(i < buck_size[index]);
+       
+       buck_val[index] = -5000;
+     }
+   }
+ }


Index: llvm/test/Programs/MultiSource/Applications/obsequi/negamax.c
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/negamax.c:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/negamax.c	Tue May 11 14:34:12 2004
***************
*** 0 ****
--- 1,552 ----
+ 
+ #include "globals.h"
+ #include "macros.h"
+ 
+ #include <time.h>
+ #include <ctype.h>
+ 
+ 
+ //#################################################################
+ // Statistics gathering variables and functions.
+ //#################################################################
+ 
+ //Determines if we should collect this data.
+ #define COLLECT_STATS
+ 
+ //=================================================================
+ // Variables used for statistics gathering.
+ //=================================================================
+ #ifdef COLLECT_STATS
+ static s32bit cut1 = 0, cut2 = 0, cut3 = 0, cut4 = 0;
+ static s32bit stat_cutoffs[40];
+ static s32bit stat_nodes[40];
+ static s32bit stat_nth_try[40][10];
+ #endif
+ 
+ //=================================================================
+ // Print the statistics which we have gathered.
+ //=================================================================
+ static void
+ print_stats()
+ {
+ #ifdef COLLECT_STATS
+   s32bit i, j;
+   
+   printf("%d %d %d %d.\n\n", cut1, cut2, cut3, cut4);
+ 
+   for(i = 0; i < 40; i++){
+     if(stat_cutoffs[i] != 0 || stat_nodes[i] != 0){
+       printf("cutoffs depth %d: (%d) %d -",
+              i, stat_nodes[i], stat_cutoffs[i]);
+       for(j = 0; j < 5; j++)
+         printf(" %d", stat_nth_try[i][j]);
+       printf(" >%d.\n", stat_nth_try[i][5]);
+     }
+   }
+ #else
+   printf("\n");
+ #endif
+ }
+ 
+ //=================================================================
+ // Initialize the statistical variables.
+ //=================================================================
+ static void
+ init_stats()
+ {
+ #ifdef COLLECT_STATS
+   s32bit i, j;
+ 
+   // zero all data.
+   for(i = 0; i < 40; i++){
+     for(j = 0; j < 6; j++)
+       stat_nth_try[i][j] = 0;
+     stat_cutoffs[i] = 0;
+     stat_nodes[i] = 0;
+   }
+ #endif
+ }
+ 
+ 
+ //#################################################################
+ // Other variables.
+ //#################################################################
+ 
+ //#define RECORD_MOVES
+ //#define DEBUG_NEGAMAX
+ 
+ 
+ extern s32bit  debug_score_move;
+ 
+ Hash_Key       g_norm_hashkey;
+ Hash_Key       g_flipV_hashkey;
+ Hash_Key       g_flipH_hashkey;
+ Hash_Key       g_flipVH_hashkey;
+ 
+ u64bit         g_num_nodes;
+ 
+ s32bit         g_first_move[2][32][32];
+ s32bit         g_empty_squares = 0;
+ 
+ s32bit         g_move_number[128];
+ 
+ #ifdef RECORD_MOVES
+ static s32bit  g_move_player[128];
+ static Move    g_move_position[128];
+ #endif
+ 
+ s32bit         g_print = 0;
+ 
+ 
+ static s32bit starting_depth;
+ 
+ 
+ //#################################################################
+ // Negamax and driver functions. (and function prototype).
+ //#################################################################
+ static s32bit
+ negamax(s32bit depth_remaining, s32bit whos_turn_t, s32bit alpha, s32bit beta);
+ 
+ 
+ //=================================================================
+ // Search for move function. (Negamax Driver)
+ //=================================================================
+ extern s32bit
+ search_for_move(char dir, s32bit *row, s32bit *col, u64bit *nodes)
+ {
+   s32bit  d, i, value = 0, num_moves;
+   Move    movelist[MAXMOVES];
+   s32bit  whos_turn;
+   Move    forcefirst;
+     
+   // Set who's turn it is.
+   if(toupper(dir) == 'V')      whos_turn = VERTICAL;
+   else if(toupper(dir) == 'H') whos_turn = HORIZONTAL;
+   else { fatal_error(1, "Invalid player.\n"); exit(1); }
+   
+   // initialize the number of empty squares.
+   g_empty_squares = 0;
+   for(i = 0; i < g_board_size[0]; i++)
+     g_empty_squares += countbits32( (~g_board[0][i+1]) );
+   
+   // zero out all the statistics variables.
+   init_stats();
+   
+   // Can we already determine a winner?
+   {
+     s32bit opponent = whos_turn ^ PLAYER_MASK;
+     
+     // stop search if game over.
+     if(g_info_totals[whos_turn].safe > g_info_totals[opponent].real){
+       // current player wins.
+       *col = *row = -1;
+       *nodes = 0;
+       return 5000;
+     }
+     
+     if(g_info_totals[opponent].safe >= g_info_totals[whos_turn].real){
+       // opponent wins.
+       *col = *row = -1;
+       *nodes = 0;
+       return -5000;
+     }
+   }
+   
+   // generate all possible moves for current player given current position.
+   num_moves = move_generator(movelist, whos_turn);
+ 
+   // This should never happen.
+   if(num_moves == 0) fatal_error(1, "No moves");
+ 
+   // should possibly sort the whole list instead of just get first.
+   forcefirst.array_index = -1;
+   score_and_get_first(movelist, num_moves, whos_turn, forcefirst);
+   sort_moves(movelist, 1, num_moves);
+ 
+   // Really this is for iterative deepening.
+   for(d = 1; d < 50; d += 44){
+ 
+     // Initialize alpha and beta.
+     s32bit alpha = -5000, beta = 5000;
+ 
+     // Re-initialize the statistics for each iteration.
+     g_num_nodes = 0;
+     init_stats();
+ 
+     // set what the starting max depth is.
+     starting_depth = d;
+         
+     // iterate through all the possible moves.
+     for(i = 0; i < num_moves; i++){
+ 
+ #ifdef DYNAMIC_POSITION_VALUES
+       init_move_value();
+       set_move_value(movelist[i], whos_turn);
+ #else
+       set_position_values();
+ #endif
+       
+       g_move_number[0] = i;
+ #ifdef RECORD_MOVES
+       g_move_player[0] = whos_turn;
+       g_move_position[0] = movelist[i];
+ #endif
+       
+       g_empty_squares -= 2;
+       toggle_move(movelist[i], whos_turn);
+       toggle_hash_code
+     (g_keyinfo[whos_turn][movelist[i].array_index][movelist[i].mask_index]);
+       check_hash_code_sanity();
+       
+       value = -negamax(d-1, whos_turn^PLAYER_MASK, -beta, -alpha);
+       
+ #ifdef DYNAMIC_POSITION_VALUES
+       unset_move_value(movelist[i], whos_turn);
+ #endif
+ 
+       g_empty_squares += 2;
+       toggle_move(movelist[i], whos_turn);
+       toggle_hash_code
+     (g_keyinfo[whos_turn][movelist[i].array_index][movelist[i].mask_index]);
+       check_hash_code_sanity();
+ 
+       printf("Move (%d,%d), value %d: %s.\n",
+              movelist[i].array_index, movelist[i].mask_index,
+              value, u64bit_to_string(g_num_nodes));
+       printf("alpha %d, beta %d.\n", alpha, beta);
+ 
+       movelist[i].info = value;
+ 
+       if(value >= beta){
+         alpha = value;
+         break;
+       }
+       if(value > alpha) {
+         alpha = value;
+       }
+     }
+ 
+     if(value >= 5000){
+       printf("Winner found: %d.\n", value);
+       if(whos_turn == HORIZONTAL){
+         *row = movelist[i].array_index;
+         *col = movelist[i].mask_index;
+       } else if(whos_turn == VERTICAL){
+         *col = movelist[i].array_index;
+         *row = movelist[i].mask_index;
+       } else {
+         fatal_error(1, "oops.");
+       }
+       
+       *nodes = g_num_nodes;
+ 
+       print_stats();
+       
+       return value;
+     }
+ 
+     // remove lossing moves from movelist.
+     {
+       s32bit rem = 0;
+       for(i = 0; i < num_moves; i++){
+         if(movelist[i].info <= -5000) rem++;
+         else if(rem > 0) movelist[i-rem] = movelist[i];
+       }
+       num_moves -= rem;
+       /*
+       for(i = 0; i < num_moves; i++){
+         printf("(%d,%d): %d.\n",
+                movelist[i].array_index, movelist[i].mask_index,
+                movelist[i].info);
+       }
+       */
+     }
+ 
+     print_stats();
+     
+     if(num_moves == 0){
+       break;
+     }
+     
+     // use a stable sort algorithm
+     {
+       Move swp;
+       s32bit max, index, j;
+       
+       for(i=0; i<num_moves; i++) {
+         max = movelist[i].info;
+         index = i;
+         
+         for(j=i+1; j < num_moves; j++)
+           if(movelist[j].info > max){
+             max = movelist[j].info;
+             index = j;
+           }
+     
+         if(index != i){
+           swp = movelist[index];
+           //          printf("%d %d\n", index, i);
+           for(j = index; j != i; j--){
+             movelist[j] = movelist[j-1];
+           }
+           movelist[i] = swp;
+         }
+       }
+     }
+     
+     printf("The value is %d at a depth of %d.\n", value, d);
+     printf("Nodes: %u.\n", (u32bit)g_num_nodes);
+   }
+ 
+   *col = *row = -1;
+   *nodes = g_num_nodes;
+ 
+   return value;
+ }
+ 
+ 
+ //=================================================================
+ // Negamax Function.
+ //=================================================================
+ static s32bit
+ negamax(s32bit depth_remaining, s32bit whos_turn_t, s32bit alpha, s32bit beta)
+ {
+   Move   movelist[MAXMOVES], best;
+   s32bit whos_turn = whos_turn_t & PLAYER_MASK;
+   s32bit opponent  = whos_turn_t ^ PLAYER_MASK;
+   s32bit value;
+   s32bit init_alpha = alpha, init_beta = beta;
+   u32bit start_nodes = g_num_nodes;
+   Move   forcefirst;
+   s32bit who_wins_value;
+ 
+   s32bit stage = 0, state = 0, true_count, i = 0, num_moves = 1;
+ 
+ #ifdef DYNAMIC_POSITION_VALUES
+   s32bit dyn_set;
+ #endif
+ 
+   // increment a couple of stats
+   g_num_nodes++;
+ #ifdef COLLECT_STATS
+   stat_nodes[starting_depth - depth_remaining]++;
+ #endif
+ 
+   // if no depth remaining stop search.
+   if( depth_remaining <= 0 ){
+     s32bit a = 0, b = 0;
+ 
+     if( (a = does_next_player_win(whos_turn, 0)) > 0 ) {
+       // current player wins.
+       return 5000;
+     }
+ 
+     if( (b = does_who_just_moved_win(opponent, 0)) >= 0 ) {
+       // opponent wins.
+       return -5000;
+     }
+   
+     return a - b;
+   }
+   
+ 
+   //------------------------------------------
+   // Can we determine a winner yet (simple check).
+   //------------------------------------------
+ 
+   // does current player win
+   if(g_info_totals[whos_turn].safe > g_info_totals[opponent].real){
+ #ifdef COLLECT_STATS
+     cut1++;
+ #endif
+     return 5000;
+   }
+   
+   // does opponent win
+   if(g_info_totals[opponent].safe >= g_info_totals[whos_turn].real){
+ #ifdef COLLECT_STATS
+     cut2++;
+ #endif
+     return -5000;
+   }
+ 
+ 
+   //------------------------------------------
+   // check transposition table
+   //------------------------------------------
+ 
+   forcefirst.array_index = -1;
+   if(hashlookup(&value, &alpha, &beta, depth_remaining,
+                 &forcefirst, whos_turn))
+     return value;
+   // since we aren't using iter deep not interested in forcefirst.
+   forcefirst.array_index = -1;
+   
+ 
+   //------------------------------------------
+   // Can we determine a winner yet (look harder).
+   //------------------------------------------
+ 
+   // does current player win
+   if( (who_wins_value = does_next_player_win(whos_turn, 0)) > 0 ) {
+ 
+ #ifdef DEBUG_NEGAMAX
+     if(random() % 1000000 == -1){
+       does_next_player_win(whos_turn, 1);
+       print_board(whos_turn);
+     }
+ #endif
+ 
+ #ifdef COLLECT_STATS
+     cut3++;
+ #endif
+     return 5000;
+   }
+     
+   // does opponent win
+   if( (who_wins_value = does_who_just_moved_win(opponent, 0)) >= 0 ) {
+ 
+ #ifdef DEBUG_NEGAMAX
+     if(who_wins_value < 3){ // && random() % 500 == -1){
+       does_who_just_moved_win(opponent, 1);
+       //  print_board(opponent);
+     }
+ #endif  
+ 
+ #ifdef COLLECT_STATS
+     cut4++;
+ #endif
+     return -5000;
+   }
+ 
+ #if 0
+   {
+     s32bit num;
+     num = move_generator_stage1(movelist, whos_turn);
+     num = move_generator_stage2(movelist, num, whos_turn);
+     if(move_generator(movelist, whos_turn) != num)
+       fatal_error(1, "NOPE\n");
+   }
+ #endif
+ 
+ 
+   //------------------------------------------
+   // Generate child nodes and examine them.
+   //------------------------------------------
+ 
+   // initialize a few variables. (some of them don't really need to be.)
+   stage = state = true_count = i = 0;
+   num_moves = 1;
+ 
+ #ifdef TWO_STAGE_GENERATION
+   true_count = move_generator_stage1(movelist, whos_turn);
+   if(true_count == 0){
+     true_count = move_generator_stage2(movelist, 0, whos_turn);
+     stage = 1;
+     if(true_count == 0) fatal_error(1, "Should always have a move.\n");
+   }
+ #else
+   true_count = move_generator(movelist, whos_turn);
+   stage = 1;
+   if(true_count == 0)   fatal_error(1, "Should always have a move.\n");
+ #endif
+   
+   // score all the moves and move the best to the front.
+   score_and_get_first(movelist, true_count, whos_turn, forcefirst);
+   
+   best = movelist[0];
+   
+   // need to sort moves and generate more moves in certain situations.
+   while(state < 3){
+     if(state == 0) {
+       state = 1;
+     } else if(state == 1){
+       sort_moves(movelist, 1, true_count);
+       num_moves = true_count;
+       if(stage == 0) state = 2;
+       else           state = 3;
+     } else {
+       num_moves = move_generator_stage2(movelist, num_moves, whos_turn);
+       state = 3;
+     }
+     
+     // Iterate through all the moves.
+     for(; i < num_moves; i++){
+ 
+       // A few statistics
+       g_move_number[starting_depth - depth_remaining] = i;
+ #ifdef RECORD_MOVES
+       g_move_player[starting_depth - depth_remaining] = whos_turn;
+       g_move_position[starting_depth - depth_remaining] = movelist[i];
+ #endif
+ 
+       // make move.
+       g_empty_squares -= 2;
+       toggle_move(movelist[i], whos_turn);
+       toggle_hash_code
+     (g_keyinfo[whos_turn][movelist[i].array_index][movelist[i].mask_index]);
+ #ifdef DYNAMIC_POSITION_VALUES
+       dyn_set = set_move_value(movelist[i], whos_turn);
+ #endif
+       
+       // recurse.
+       value = -negamax(depth_remaining-1,whos_turn^PLAYER_MASK,
+                        -beta, -alpha);
+       
+       // undo move.
+       g_empty_squares += 2;
+       toggle_move(movelist[i], whos_turn);
+       toggle_hash_code
+     (g_keyinfo[whos_turn][movelist[i].array_index][movelist[i].mask_index]);
+ #ifdef DYNAMIC_POSITION_VALUES
+       if(dyn_set != 0) unset_move_value(movelist[i], whos_turn);
+ #endif
+ 
+ #if 0
+       if(starting_depth - depth_remaining == 8) {
+         s32bit g;
+         
+         printf("goof:");
+         
+         for(g = 0; g < 8; g++){
+           printf(" :%c:%d(%d,%d)", 
+                  (g_move_player[g] == VERTICAL) ? 'V' : 'H',
+                  g_move_number[g],
+                  g_move_position[g].array_index - 1,
+                  g_move_position[g].mask_index - 1);
+         }
+         printf("\n");
+       }
+ #endif
+ 
+       // If this is a cutoff, break.
+       if(value >= beta){
+         alpha = value;
+         best  = movelist[i];
+         
+ #ifdef COLLECT_STATS
+         stat_cutoffs[starting_depth - depth_remaining]++;
+         if(i < 5) stat_nth_try[starting_depth - depth_remaining][i]++;
+         else      stat_nth_try[starting_depth - depth_remaining][5]++;
+ #endif
+         break;
+       }
+       
+       // If the current value is greater than alpha, increase alpha.
+       if(value > alpha) {
+         alpha = value;
+         best  = movelist[i];
+       }
+     }
+ 
+     // If we have broken out of previous FOR loop make sure we break out
+     //   of this loop as well.
+     if(value >= beta) break;
+   }
+   
+   // save the position in the hashtable
+   hashstore(alpha, init_alpha, init_beta, (g_num_nodes - start_nodes) >> 5,
+             depth_remaining, best, whos_turn);
+   
+   return alpha;
+ }


Index: llvm/test/Programs/MultiSource/Applications/obsequi/obsequi.c
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/obsequi.c:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/obsequi.c	Tue May 11 14:34:12 2004
***************
*** 0 ****
--- 1,620 ----
+ //********************************************************
+ // This file part of my Obsequi front end.
+ //********************************************************
+ //
+ // Copyright (C) 2001 Nathan Bullock
+ //
+ // 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
+ //
+ //********************************************************
+ //  Email address - bullock at cs.ualberta.ca
+ //  Web address   - www.cs.ualberta.ca/~bullock
+ //********************************************************
+ 
+ #include "utils.h"
+ 
+ #include <signal.h>
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <sys/time.h>
+ #include <ctype.h>
+ 
+ #include "cppflags.h"
+ #include "interface.h"
+ 
+ 
+ //########################################################
+ // Function templates.
+ //########################################################
+ 
+ // handle command line options.
+ static void   decode_switches     (int argc, char **argv);
+ 
+ // signal handlers.
+ static void   sig_int_setup       ();
+ static void   sig_int_handler     (int sig);
+ static void   sig_alrm_setup      ();
+ static void   sig_alrm_handler    (int sig);
+ static void   sig_block           ();
+ static void   set_stop_alrm       (long minutes);
+ 
+ // main command loop functions.
+ static void   get_solve_command   ();
+ 
+ // lock file stuff.
+ static void   get_solve_command_from_lock_file();
+ static void   write_to_lock_file(char winner, const char* num_nodes);
+ 
+ 
+ //########################################################
+ // Global variables.
+ //########################################################
+ 
+ // Determines if we will have an alarm checking the input every so often.
+ static s32bit main_batch = 1;
+ 
+ // Determines if we should be reading a lock file and what it's name is.
+ static char  *lock_file = NULL;
+ 
+ // Determines if we should be stopping program after x minutes.
+ static long   stop_minutes = 0;
+ 
+ static char   main_whos_turn;
+ 
+ 
+ //########################################################
+ // Entry point to obsequi.
+ //########################################################
+ int
+ main(int argc, char** argv)
+ {
+   decode_switches(argc, argv);
+ 
+   if(lock_file){
+     get_solve_command_from_lock_file();
+     if(stop_minutes) set_stop_alrm(stop_minutes);
+   } else {
+     get_solve_command();
+     if(!main_batch) sig_alrm_setup();
+   }
+   
+   sig_int_setup();
+   
+   // start solver.
+   {
+     s32bit row, col;
+     u64bit nodes;
+     s32bit score;
+     const char*  num_nodes;
+     
+     score = search_for_move(main_whos_turn, &row, &col, &nodes);
+     
+     sig_block();
+     
+     num_nodes = u64bit_to_string(nodes);
+     
+     // print results.
+     if(score >= 5000){
+       printf("winner %c, move (%d,%d), nodes %s.\n",
+              main_whos_turn, row, col, num_nodes);
+     } else if(score <= 5000){
+       printf("winner %c, move (%d,%d), nodes %s.\n",
+              (main_whos_turn == 'V') ? 'H' : 'V',
+              row, col, num_nodes);
+     } else {
+       printf("Undecided, Best score: %d, nodes %s.\n",
+              score, num_nodes);
+     }
+     
+     fflush(stdout);
+     
+     if(lock_file){
+       char winner = 0;
+       
+       if(score >= 5000) winner = main_whos_turn;
+       else if(score <= -5000) winner = (main_whos_turn == 'V') ? 'H' : 'V';
+       else fatal_error(1, "Undecided.\n");
+       
+       write_to_lock_file(winner, num_nodes);
+     }
+   }
+   
+   // if not in batch mode don't exit until stdin has been closed.
+   fcntl(STDIN_FILENO, F_SETFL, 0);
+   if (!main_batch){
+     while(getchar() != EOF);
+   }
+   
+   return 0;
+ }
+ 
+ 
+ //########################################################
+ // Main input - output commands.
+ //########################################################
+ 
+ //========================================================
+ // This function reads stdin one line at a time.
+ // It initializes the solver engine when it finds a line of the format:
+ //
+ //  "solve rows m cols n bx0,y0;x1,y1;...;x,y f"
+ //    where:
+ //     - m is the number of rows.
+ //     - n is the number of cols.
+ //     - bx0,y0 is the position of a block on the board.
+ //     - f is H if it is horizontals turn and V if verticals turn.
+ //
+ // It discards all input which does not match this format and
+ //   writes an error message to stderr.
+ //========================================================
+ static void
+ get_solve_command()
+ {
+   char*   line      = NULL, *blocks = NULL;
+   size_t  line_size = 0, len;
+ 
+   // Board info for the board which we are solving.
+   u32bit num_rows;
+   u32bit num_cols;
+   s32bit board[30][30];
+   char   c1, c2;
+ 
+   s32bit r, c;
+     
+   while( (len = getline(&line, &line_size, stdin)) != -1){
+     s32bit t;
+     
+     if(len > 0){
+       if(blocks != NULL) blocks = realloc(blocks, line_size);
+       else               blocks = malloc(line_size);
+     } else continue;
+     line[len - 1] = 0;
+     
+     t = sscanf(line, "solve rows %u cols %u %c%s %c",
+                &num_rows, &num_cols, &c1, blocks, &c2);
+     
+     if(t != 3 && t != 5){
+       fprintf(stderr, "Invalid command: '%s'.\n", line);
+       continue;
+     }
+           
+     if(num_rows > 30){
+       fprintf(stderr, "Too many rows: %u > 30.\n", num_rows);
+       continue;
+     }
+     
+     if(num_cols > 30){
+       fprintf(stderr, "Too many cols: %u > 30.\n", num_cols);
+       continue;
+     }
+       
+     if(num_cols * num_rows > 256){
+       fprintf(stderr,
+               "Search space too large: %u > 256.\n", num_cols*num_rows);
+       continue;
+     }
+ 
+     for(r = 0; r < 30; r++)
+       for(c = 0; c < 30; c++) board[r][c] = 0;
+     
+     if(t == 5) {
+       char *tok;
+       
+       c1 = toupper(c1);
+       if(c1 != 'B') {
+         fprintf(stderr, "Invalid command: '%s'.\n", line);
+         continue;
+       }
+ 
+       tok = strtok(blocks, ";");
+       while(tok != NULL){
+         if(sscanf(tok, "%u,%u", &r, &c) != 2){
+           fprintf(stderr, "Invalid block string: '%s'.\n", tok);
+           c1 = 0;
+           break;
+         }
+         if(r >= num_rows || c >= num_cols){
+           fprintf(stderr, "Invalid block string: '%s'.\n", tok);
+           c1 = 0;
+           break;
+         }
+ 
+         board[r][c] = 1;
+         
+         tok = strtok(NULL, ";");
+       }
+       if(c1 == 0) continue;
+     } else {
+       c2 = c1;
+     }
+     
+     c2 = toupper(c2);
+     if(c2 != 'V' && c2 != 'H'){
+       fprintf(stderr, "Invalid players turn: %c.\n", c2);
+       continue;
+     }
+     
+     // everything should be initialized properly at this point.
+     printf("Starting\n");
+     fflush(stdout);
+     break;
+   }
+ 
+   if(len == -1) fatal_error(1, "No valid command given.\n");
+ 
+   /*
+   main_num_rows  = num_rows;
+   main_num_cols  = num_cols;
+ 
+   for(r = 0; r < 30; r++)
+     for(c = 0; c < 30; c++)
+       main_board[r][c] = board[r][c];
+   */
+   main_whos_turn = c2;
+ 
+   initialize_board(num_rows, num_cols, board);
+   
+   //print_external(); exit(0);
+ 
+   free(line);
+   free(blocks);
+ }
+ 
+ 
+ //========================================================
+ // Non blocking input loop.
+ //========================================================
+ static void
+ get_other_commands()
+ {
+   static size_t  line_size;
+   static char   *line;
+   char c1;
+   
+   fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
+   
+   // get next line of input, exit at end of input.
+   while (getline(&line, &line_size, stdin) > 0){
+ 
+     printf(line);
+     
+     // stop the search.
+     if(sscanf(line, "stop%c", &c1) == 1){
+       exit(0);
+     }
+ 
+     /*
+     // print info (whatever that is).
+     else if(sscanf(line, "info%c", &c1) == 1){
+       stringify_stack(&line, &line_size);
+       fprintf(stderr, "%s", line);
+     }
+     */
+ 
+     else {
+       fprintf(stderr, "Invalid command.\n");
+     }
+   }
+ 
+   fflush(stderr);
+   clearerr(stdin);
+ }
+ 
+ 
+ //########################################################
+ // Obsequi takes a number of arguments
+ //  -e print flags used at compile time.
+ //  -h print out help message and exit.
+ //  -l specify file which contains a position to solve.
+ //  -t specify maximum time limit for solving position.
+ //        only works when using a "lock file" -l.
+ //  -v print version information.
+ //  -w wait for standard in to be closed before exiting.
+ //########################################################
+ static void
+ decode_switches(int argc, char **argv)
+ {
+   int c;
+   
+   while ((c = getopt(argc, argv, "wehl:t:v")) != -1){
+     switch(c){
+     case 'e':
+       printf(option_string);
+       exit(0);
+       
+     case 'h':
+       printf("No help available in this version.\n");
+       exit(0);
+       
+     case 'l':
+       lock_file = strdup(optarg);
+       break;
+       
+     case 't':
+       stop_minutes = atoi(optarg);
+       break;
+       
+     case 'v':
+       printf("No version info available.\n");
+       exit(0);
+       
+     case 'w':
+       main_batch = 0;
+       break;
+       
+     default:
+       fatal_error(1, "Invalid option: '-%c'.\n", c);
+     }
+   }
+ 
+   if(optind < argc)
+     fatal_error(1, "Extra unknown options on command line.\n");
+ }
+ 
+ 
+ 
+ //########################################################
+ // Signal handling stuff.
+ //########################################################
+ 
+ //========================================================
+ // sig int stuff
+ //========================================================
+ static void
+ sig_int_handler(int sig)
+ {
+   const char* str;
+ 
+   str = current_search_state();
+ 
+   fprintf(stderr, "%s\n", str);
+ 
+   fflush(stderr);
+ }
+ 
+ static void
+ sig_int_setup()
+ {
+   struct sigaction   act;
+   
+   //  sigemptyset(&act.sa_mask);
+   sigfillset(&act.sa_mask);
+   act.sa_flags = 0;
+ 
+   act.sa_handler = sig_int_handler;
+   if ( sigaction(SIGINT, &act, NULL) )
+     fatal_error(1, "`sigaction' failed.");
+ }
+ 
+ 
+ //========================================================
+ // sig alarm stuff
+ //========================================================
+ static void
+ sig_alrm_handler(int sig)
+ {
+   get_other_commands();
+ }
+ 
+ static void
+ stop_alrm_handler(int sig)
+ {
+   exit(0);
+ }
+ 
+ static void
+ set_stop_alrm(long minutes)
+ {
+   struct sigaction   act;
+   struct itimerval itime;
+ 
+   //  sigemptyset(&act.sa_mask);
+   sigfillset(&act.sa_mask);
+   act.sa_flags = 0;
+ 
+   act.sa_handler = stop_alrm_handler;
+   if ( sigaction(SIGVTALRM, &act, NULL) )
+     fatal_error(1, "`sigaction' failed.");
+ 
+   itime.it_interval.tv_sec  = minutes * 60;
+   itime.it_interval.tv_usec = 0;
+   itime.it_value.tv_sec  = minutes * 60;
+   itime.it_value.tv_usec = 0;
+   
+   if ( setitimer(ITIMER_VIRTUAL, &itime, NULL) )
+     fatal_error(1, "`setitimer' failed.\n");
+ }
+ 
+ static void
+ sig_alrm_setup()
+ {
+   struct sigaction   act;
+   struct itimerval   itime;
+ 
+   //  sigemptyset(&act.sa_mask);
+   sigfillset(&act.sa_mask);
+   act.sa_flags = 0;
+ 
+   act.sa_handler = sig_alrm_handler;
+   if ( sigaction(SIGALRM, &act, NULL) )
+     fatal_error(1, "`sigaction' failed.");
+ 
+   itime.it_interval.tv_sec  = 2;
+   itime.it_interval.tv_usec = 0;
+   itime.it_value.tv_sec  = 1;
+   itime.it_value.tv_usec = 0;
+   
+   if ( setitimer(ITIMER_REAL, &itime, NULL) )
+     fatal_error(1, "`setitimer' failed.\n");
+ }
+ 
+ 
+ //========================================================
+ // block all new signals stuff
+ //========================================================
+ static void
+ sig_block()
+ {
+   sigset_t set;
+   sigemptyset(&set);
+   sigaddset(&set, SIGALRM);
+   sigaddset(&set, SIGINT);
+ 
+   sigprocmask(SIG_BLOCK, &set, NULL);
+ }
+ 
+ 
+ //########################################################
+ // Lock and read lock file.
+ //########################################################
+ 
+ //========================================================
+ // Some local variables for the lock file stuff.
+ //========================================================
+ static s32bit lock_file_offset;
+ 
+ static s32bit
+ next_valid_pos(const char *line, s32bit line_pos)
+ {
+   s32bit i, state = 0;
+   for(i = line_pos; line[i] != 0; i++){
+     if(line[i] == ' ') {
+       if(state != 0) state = 2;
+     } else {
+       if(state == 2) break;
+       state = 1;
+     }
+   }
+   return i;
+ }
+ 
+ 
+ static void
+ write_to_lock_file(char winner, const char* num_nodes)
+ {
+   FILE* file = NULL;
+   
+   if( (file = fopen(lock_file, "r+")) == NULL )
+     fatal_error(1, "Can't open file.\n");
+   
+   //  if(lockf(fileno(file), F_LOCK, 0) != 0)
+   //  fatal_error(1, "Lock failed.\n");
+ 
+   printf("%s\n", lock_file);
+ 
+   fseek(file, lock_file_offset, SEEK_SET);
+   fprintf(file, "%c %15s", winner, num_nodes);
+   fflush(file);
+   
+   //  lockf(fileno(file), F_ULOCK, 0);
+   fclose(file);
+ }
+ 
+ 
+ static void
+ get_solve_command_from_lock_file()
+ {
+   FILE* file = NULL;
+   
+   char*   line      = NULL;
+   size_t  line_size = 0, len, line_pos;
+ 
+   // Board info for the board which we are solving.
+   u32bit num_rows;
+   u32bit num_cols;
+   s32bit board[30][30];
+   char player = 0;
+ 
+   s32bit r, c;
+   
+   if( (file = fopen(lock_file, "r+")) == NULL )
+     fatal_error(1, "Can't open file.\n");
+   
+   // if(lockf(fileno(file), F_LOCK, 0) != 0)
+   //   fatal_error(1, "Lock failed.\n");
+ 
+   printf("%s\n", lock_file);
+   
+   while( lock_file_offset = ftell(file),
+          (len = getline(&line, &line_size, file)) != -1){
+     // if line has a length of 0 line[0] will be '\0'.
+     if(line[0] != 'A') continue;
+ 
+     printf("%s", line);
+     
+     if(len <= 18) fatal_error(1, line);
+     
+     if(sscanf(line + 18, "(%d,%d)", &num_rows, &num_cols) != 2)
+       fatal_error(1, "Invalid row and columns.\n%s\n", line);
+     
+     if(num_rows > 30)
+       fatal_error(1, "Too many rows: %u > 30.\n", num_rows);
+     if(num_cols > 30)
+       fatal_error(1, "Too many cols: %u > 30.\n", num_cols);
+     if(num_cols * num_rows > 128)
+       fatal_error(1, "Search space too large: %u > 256.\n", num_cols*num_rows);
+     
+     for(r = 0; r < 30; r++)
+       for(c = 0; c < 30; c++) board[r][c] = 0;
+     
+     line_pos = 18;
+     
+     while(1){
+       s32bit ignore;
+       
+       line_pos = next_valid_pos(line, line_pos);
+       
+       if(line_pos >= len) break;
+       
+       if(sscanf(line + line_pos, ":%c:%d(%d,%d)", &player,
+                 &ignore, &r, &c) != 4)
+         break;
+       
+       printf("%c %d %d\n", player, r, c);
+       
+       if(player == 'V'){
+         if(board[c][r] == 1 ||  board[c+1][r] == 1)
+           fatal_error(1, line);
+         board[c][r] = board[c+1][r] = 1;
+       } else if(player == 'H'){
+         if(board[r][c] == 1 || board[r][c+1] == 1)
+           fatal_error(1, line);
+         board[r][c] = board[r][c+1] = 1;
+       } else fatal_error(1, "Invalid player.\n");
+     }
+     
+     // everything should be initialized properly at this point.
+     printf("Starting\n");
+     fflush(stdout);
+     break;
+   }
+ 
+   if(len == -1) fatal_error(1, "No valid command given.\n");
+   
+   fseek(file, lock_file_offset, SEEK_SET);
+   fprintf(file, "W");
+   fflush(file);
+   
+   if(player == 'V') main_whos_turn = 'H';
+   else if(player == 'H') main_whos_turn = 'V';
+   else  fatal_error(1, "Invalid player.\n");
+ 
+   initialize_board(num_rows, num_cols, board);
+   
+   free(line);
+ 
+   //  lockf(fileno(file), F_ULOCK, 0);
+   fclose(file);
+ }


Index: llvm/test/Programs/MultiSource/Applications/obsequi/position_values.c
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/position_values.c:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/position_values.c	Tue May 11 14:34:13 2004
***************
*** 0 ****
--- 1,178 ----
+ 
+ 
+ #include "globals.h"
+ 
+ //#################################################################
+ // Give all the positions for this PLAYER which are symmetrical
+ //  to the position (ROW, COL) a value of VALUE.
+ //#################################################################
+ static void
+ set_position_value(s32bit player, s32bit row, s32bit col, s32bit value)
+ {
+   s32bit num_rows, num_cols;
+   
+   num_rows = g_board_size[player] + 1;
+   num_cols = g_board_size[player^PLAYER_MASK];
+ 
+   //printf("1 - %d %d %d\n", player, row, col);
+   g_first_move[player][row][col]                   = value;
+   //printf("2 - %d %d %d\n", player, num_rows-row, col);
+   g_first_move[player][num_rows-row][col]          = value;
+   //printf("3 - %d %d %d\n", player, num_rows-row, num_cols-col);
+   g_first_move[player][num_rows-row][num_cols-col] = value;
+   //  printf("4 - %d %d %d\n", player, row, num_cols-col);
+   g_first_move[player][row][num_cols-col]          = value;
+ }
+ 
+ 
+ #ifdef DYNAMIC_POSITION_VALUES
+ //#################################################################
+ // If we are using dynamic position values then these are the
+ //  functions (and variables) which we use to set these values.
+ //#################################################################
+ 
+ //=================================================================
+ // Variable to keep track of value we will give to the next position.
+ //=================================================================
+ static s32bit set_move_value_current = 127;
+ 
+ //=================================================================
+ // Initialize all positions with a value of 0
+ //=================================================================
+ extern void
+ init_move_value     ()
+ {
+   s32bit i, j, k;
+   set_move_value_current = 127;
+   
+   for(i = 0; i < 2; i++)
+     for(j = 0; j < 32; j++)
+       for(k = 0; k < 32; k++)
+         g_first_move[i][j][k] = 0;
+ }
+ 
+ //=================================================================
+ // Set the value of the positions symetrical to MOVE.
+ //  return 0 if these positions already have a value, otherwise 1.
+ //=================================================================
+ extern s32bit
+ set_move_value      (Move move, s32bit player)
+ {
+   if(g_first_move[player][move.array_index][move.mask_index] != 0)
+     return 0;
+   
+   set_position_value(player, move.array_index, move.mask_index,
+                      set_move_value_current--);
+   return 1;
+ }
+ 
+ //=================================================================
+ // UnSet the value of the positions symetrical to MOVE.
+ //  Shouldn't be called if when 'set' was called it returned a value of 0.
+ //=================================================================
+ extern void
+ unset_move_value    (Move move, s32bit player)
+ {
+   set_move_value_current
+     = g_first_move[player][move.array_index][move.mask_index];
+   
+   set_position_value(player, move.array_index, move.mask_index, 0);
+ }
+ 
+ #else
+ //#################################################################
+ // If we are using dynamic position values then these are the
+ //  functions which we use to set these values.
+ //#################################################################
+ 
+ //=================================================================
+ // Set the value of all the positions on the board.
+ //  We only do this once at the start of the search.
+ //=================================================================
+ extern void
+ set_position_values()
+ {
+   s32bit i, j, k, count;
+   
+   // set them all to zero.
+   for(i = 0; i < 2; i++)
+     for(j = 0; j < 32; j++)
+       for(k = 0; k < 32; k++)
+         g_first_move[i][j][k] = 0;
+ 
+ #if 0
+   // Set values using very simple scheme.
+   for(i = 0; i < 2; i++){
+     count = 64;
+     for(j = 1; j < (g_board_size[i]+3)/2; j++){
+       for(k = 1; k < (g_board_size[i^PLAYER_MASK]/2)+1; k++){
+         if(g_first_move[i][j][k] == 0)
+           set_position_value(i, j, k, --count);
+       }
+     }
+   }
+ #elif 1
+   // Set values using a more complex (seems to be better) scheme.
+   for(i = 0; i < 2; i++){
+     count = 127;
+     for(j = 2; j < (g_board_size[i]+3)/2; j+=2){
+       for(k = 1; k < (g_board_size[i^PLAYER_MASK]/2)+1; k+=2){
+         set_position_value(i, j, k, --count);
+       }
+     }
+   }
+   for(i = 0; i < 2; i++){
+     count = 90;
+     for(j = 2; j < (g_board_size[i]+3)/2; j+=2){
+       for(k = 1; k < (g_board_size[i^PLAYER_MASK]/2)+1; k++){
+         if(g_first_move[i][j][k] == 0)
+           set_position_value(i, j, k, --count);
+       }
+     }
+   }
+   for(i = 0; i < 2; i++){
+     count = 70;
+     for(j = 3; j < (g_board_size[i]+3)/2; j++){
+       for(k = 1; k < (g_board_size[i^PLAYER_MASK]/2)+1; k+=2){
+         if(g_first_move[i][j][k] == 0)
+           set_position_value(i, j, k, --count);
+       }
+     }
+   }
+   for(i = 0; i < 2; i++){
+     count = 50;
+     for(j = 3; j < (g_board_size[i]+3)/2; j++){
+       for(k = 1; k < (g_board_size[i^PLAYER_MASK]/2)+1; k++){
+         if(g_first_move[i][j][k] == 0)
+           set_position_value(i, j, k, --count);
+       }
+     }
+   }
+   for(i = 0; i < 2; i++){
+     count = 30;
+     for(j = 1; j < (g_board_size[i]+3)/2; j++){
+       for(k = 1; k < (g_board_size[i^PLAYER_MASK]/2)+1; k++){
+         if(g_first_move[i][j][k] == 0)
+           set_position_value(i, j, k, --count);
+       }
+     }
+   }
+ #endif
+ 
+   // print the values. (mostly for debugging)
+ #if 0
+   for(i = 0; i < 2; i++){
+     for(j = 0; j < 32; j++){
+       for(k = 0; k < 32; k++){
+         printf("%d ", g_first_move[i][j][k]);
+       }
+       printf("\n");
+     }
+     printf("\n");
+   }
+   exit(0);
+ #endif
+   
+ }
+ 
+ #endif


Index: llvm/test/Programs/MultiSource/Applications/obsequi/structs.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/structs.h:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/structs.h	Tue May 11 14:34:13 2004
***************
*** 0 ****
--- 1,266 ----
+ 
+ 
+ #ifndef STRUCTS_H
+ #define STRUCTS_H
+ 
+ #include "utils.h"
+ 
+ //########################################################
+ // Basic board info which we keep track of.
+ //########################################################
+ typedef struct
+ {
+   s32bit safe;
+   s32bit real;
+   s32bit mobility;
+ } Basic_Info;
+ 
+ 
+ //########################################################
+ // Info we need to describe a move.
+ //########################################################
+ typedef struct
+ {
+   s32bit array_index;
+   s32bit mask_index;
+   s32bit info;
+ } Move;
+ 
+ 
+ //########################################################
+ // Info we need for each entry in the hashtable.
+ //########################################################
+ typedef struct
+ {
+   // uniquely identifies a board position.
+   u32bit key[4];
+ 
+   // if real num of nodes exceeds ULONG_MAX set to ULONG_MAX.
+   //   or maybe we could just shift the bits (larger granularity).
+   u32bit nodes;
+ 
+   // uniquely identifies the previous best move for this position.
+   u8bit  best_move;
+ 
+   // depth of the search when this value was determined.
+   u8bit  depth : 7;
+ 
+   // whos turn it is.
+   u8bit  whos_turn : 1;
+ 
+   // value of node determined with a search to `depth`.
+   s16bit value : 14;
+ 
+   // value of node determined with a search to `depth`.
+   u16bit type : 2; //UPPER, LOWER, EXACT.
+ } Hash_Entry;
+ 
+ 
+ //########################################################
+ // structure used to store current key and it's hash code.
+ //########################################################
+ typedef struct
+ {
+   u32bit key[4];
+   s32bit code;
+ } Hash_Key;
+ 
+ 
+ //########################################################
+ // table_keyinfo
+ //########################################################
+ typedef struct
+ {
+   s32bit bit1_index;
+   s32bit bit2_index;
+   u32bit hash_code;
+ } KeyInfo_s;
+ 
+ typedef struct
+ {
+   KeyInfo_s norm;
+   KeyInfo_s flipV;
+   KeyInfo_s flipH;
+   KeyInfo_s flipVH;
+ } KeyInfo;
+ 
+ #endif
+ 
+ #ifndef STRUCTS_H
+ 
+ extern void
+ hashstore(s32bit value, s32bit alpha, s23bit beta,
+           u64bit nodes, int depth, struct move best, int color)
+ {
+   /* write the record anyway where the index is*/
+   int32 index, minindex;
+   int mindepth=1000,iter=0;
+   int from,to;
+   
+   if(depth<0) return;
+   hashstores++;
+   
+   if(realdepth < DEEPLEVEL) {
+     /* its in the "deep" hashtable: take care not to overwrite other entries */
+     index=Gkey&HASHMASKDEEP;
+     minindex=index;
+     while(iter<HASHITER) {
+       if(deep[index].lock==Glock || deep[index].lock==0) {
+         /* found an index where we can write the entry */
+         deep[index].lock=Glock;
+         deep[index].info=(int16) (depth&DEPTH);
+         if(color==BLACK) {
+           deep[index].best=best.bm|best.bk;
+           deep[index].info|=HASHBLACK;
+         } else
+           deep[index].best=best.wm|best.wk;
+         
+         deep[index].value=(sint16)value;
+         /* determine valuetype */
+         if(value>=beta) {deep[index].info|=LOWER;return;}
+         if(value>alpha) {deep[index].info|=EXACT;return;}
+         deep[index].info|=UPPER;
+         return;
+       } else {
+         if( hashdepth(deep[index].info) < mindepth) {
+           minindex=index;
+           mindepth=hashdepth(deep[index].info);
+         }
+       }
+       iter++;
+       index++;
+       index=index&HASHMASKDEEP;
+     }
+     /* if we arrive here it means we have gone through all hashiter
+        entries and all were occupied. in this case, we write the entry
+        to minindex */
+     if(mindepth>(depth)) return;
+     deep[minindex].lock=Glock;
+     deep[minindex].info=(int16) (depth);
+     if(color==BLACK)
+       deep[minindex].best=best.bm|best.bk;
+     else
+       deep[minindex].best=best.wm|best.wk;
+     deep[minindex].info|=(int16)((color>>1)<<13);
+     deep[minindex].value=value;
+       /* determine valuetype */
+     if(value>=beta) {deep[minindex].info|=LOWER;return;}
+     if(value>alpha) {deep[minindex].info|=EXACT;return;}
+     deep[minindex].info|=UPPER;
+     return;
+     /* and return */
+   } else {
+       index=Gkey&HASHMASKSHALLOW;
+       if( hashdepth(shallow[index].info) <= depth )
+         /* replace the old entry if the new depth is larger */
+         {
+           shallow[index].lock=Glock;
+           shallow[index].info=(int16)depth;
+           shallow[index].value=(sint16)value;
+           if(color==BLACK)
+             {
+               shallow[index].best=best.bm|best.bk;
+               shallow[index].info|=HASHBLACK;
+             }
+           else
+             shallow[index].best=best.wm|best.wk;
+           
+           /* determine valuetype */
+           
+           if(value>=beta) {shallow[index].info|=LOWER;return;}
+           if(value>alpha) {shallow[index].info|=EXACT;return;}
+           shallow[index].info|=UPPER;
+         }
+     }
+   return;
+ }
+ 
+ int hashlookup(int *value, int *alpha, int *beta, int depth, int32 *forcefirst, int color)
+ {
+   int32 index;
+   int iter=0;
+   
+   hashsearch++;
+   
+   if(realdepth<DEEPLEVEL)
+     /* a position in the "deep" hashtable - it's important to find it since */
+     /* the effect is larger here! */
+     {
+       hashhit++;
+       index=Gkey&HASHMASKDEEP;
+       while(iter<HASHITER)
+       	{
+           if(deep[index].lock==Glock && (hashcolor(deep[index].info)>>13)==(color>>1))
+             {
+               /* we have found the position */
+               hashhit++;
+               /* move ordering */
+               *forcefirst=deep[index].best;
+               /* use value if depth in hashtable >= current depth)*/
+               if(hashdepth(deep[index].info)>=depth)
+                 {
+                   /* if it's an exact value we can use it */
+                   if(hashvaluetype(deep[index].info) == EXACT)
+                     {
+                       *value=deep[index].value;
+                       return 1;
+                     }
+                   /* lower bound */
+                   if(hashvaluetype(deep[index].info) == LOWER)
+                     {
+                       if(deep[index].value>=(*beta)) {*value=deep[index].value;return 1;}
+                       if(deep[index].value>(*alpha)) {*alpha=deep[index].value;}
+                       return 0;
+                     }
+                   /* upper bound */
+                   if(hashvaluetype(deep[index].info) == UPPER)
+                     {
+                       if(deep[index].value<=*alpha) {*value=deep[index].value;return 1;}
+                       if(deep[index].value<*beta)   {*beta=deep[index].value;}
+                       return 0;
+                     }
+                 }
+             }
+           iter++;
+           index++;
+           index&=HASHMASKDEEP;
+       	}
+       return 0;
+     }
+   /* use shallow hashtable */
+   else
+     {
+       index=Gkey&HASHMASKSHALLOW;
+       if(shallow[index].lock==Glock && (hashcolor(shallow[index].info)>>13)==(color>>1))
+         {
+           hashhit++;
+           /*found the right entry!*/
+           *forcefirst=shallow[index].best;
+           if(hashdepth(shallow[index].info)>=depth)
+             {
+               if(hashvaluetype(shallow[index].info) == EXACT)
+             	{
+                   *value=shallow[index].value;
+                   return 1;
+                 }
+               /* lower bound */
+               if(hashvaluetype(shallow[index].info) == LOWER)
+             	{
+                   if(shallow[index].value>=*beta) {*value=shallow[index].value;return 1;}
+                   if(shallow[index].value>*alpha) {*alpha=shallow[index].value;}
+                   return 0;
+                 }
+               /* upper bound */
+               if(hashvaluetype(shallow[index].info) == UPPER)
+             	{
+                   if(shallow[index].value<=*alpha) {*value=shallow[index].value;return 1;}
+                   if(shallow[index].value<*beta)   {*beta=shallow[index].value;}
+                   return 0;
+                 }
+             }
+       	}
+     }
+   return 0;
+ }
+ */
+ #endif


Index: llvm/test/Programs/MultiSource/Applications/obsequi/tables.c
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/tables.c:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/tables.c	Tue May 11 14:34:13 2004
***************
*** 0 ****
--- 1,227 ----
+ 
+ 
+ #include "globals.h"
+ 
+ #ifdef COUNTBITS16
+ s32bit countbits16[65536];
+ 
+ static void
+ init_countbits()
+ {
+   s32bit i;
+   
+   countbits16[0] = 0;
+   
+   for(i = 1; i < 65536; i++){
+     countbits16[i] = (i & 1) + countbits16[i >> 1];
+   }
+ }
+ #endif
+ 
+ #ifdef COUNTBITS8
+ s32bit countbits8[256];
+ 
+ static void
+ init_countbits()
+ {
+   s32bit i;
+   
+   countbits8[0] = 0;
+   
+   for(i = 1; i < 256; i++){
+     countbits8[i] = (i & 1) + countbits8[i >> 1];
+   }
+ }
+ #endif
+ 
+ #ifdef LASTBIT16
+ s32bit lastbit16[65536];
+ 
+ static void
+ init_lastbit()
+ {
+   s32bit i;
+   
+   for(i = 1; i < 65536; i++){
+     if(i&NTH_BIT(0)) {lastbit16[i] = 0; continue;}
+     if(i&NTH_BIT(1)) {lastbit16[i] = 1; continue;}
+     if(i&NTH_BIT(2)) {lastbit16[i] = 2; continue;}
+     if(i&NTH_BIT(3)) {lastbit16[i] = 3; continue;}
+     if(i&NTH_BIT(4)) {lastbit16[i] = 4; continue;}
+     if(i&NTH_BIT(5)) {lastbit16[i] = 5; continue;}
+     if(i&NTH_BIT(6)) {lastbit16[i] = 6; continue;}
+     if(i&NTH_BIT(7)) {lastbit16[i] = 7; continue;}
+     if(i&NTH_BIT(8)) {lastbit16[i] = 8; continue;}
+     if(i&NTH_BIT(9)) {lastbit16[i] = 9; continue;}
+     if(i&NTH_BIT(10)) {lastbit16[i] = 10; continue;}
+     if(i&NTH_BIT(11)) {lastbit16[i] = 11; continue;}
+     if(i&NTH_BIT(12)) {lastbit16[i] = 12; continue;}
+     if(i&NTH_BIT(13)) {lastbit16[i] = 13; continue;}
+     if(i&NTH_BIT(14)) {lastbit16[i] = 14; continue;}
+     if(i&NTH_BIT(15)) {lastbit16[i] = 15; continue;}
+   }
+   
+   lastbit16[0] = 100;
+ }
+ #endif
+ 
+ #ifdef LASTBIT8
+ s32bit lastbit8[256];
+ 
+ static void
+ init_lastbit()
+ {
+   s32bit i;
+   
+   for(i = 1; i < 256; i++){
+     if(i&NTH_BIT(0)) {lastbit8[i] = 0; continue;}
+     if(i&NTH_BIT(1)) {lastbit8[i] = 1; continue;}
+     if(i&NTH_BIT(2)) {lastbit8[i] = 2; continue;}
+     if(i&NTH_BIT(3)) {lastbit8[i] = 3; continue;}
+     if(i&NTH_BIT(4)) {lastbit8[i] = 4; continue;}
+     if(i&NTH_BIT(5)) {lastbit8[i] = 5; continue;}
+     if(i&NTH_BIT(6)) {lastbit8[i] = 6; continue;}
+     if(i&NTH_BIT(7)) {lastbit8[i] = 7; continue;}
+   }
+   
+   lastbit8[0] = 100;
+ }
+ #endif
+ 
+ #ifdef COUNTMOVES_TABLE
+ s32bit move_table16[65536];
+ 
+ static void
+ init_movetable()
+ {
+   u32bit i = 0, mask, tmp = 0, count;
+   
+   while(i < 65536){
+     mask = i;
+     count = 0;
+     
+     while(mask){
+       tmp = (mask&-mask);           // least sig bit of m
+       mask &= ~(tmp | (tmp << 1));  // remove bit and next bit.
+       count++;
+     }
+ 
+ #ifndef BOARD_SIZE_LT_16
+     if(tmp & 0x00008000) count |= 0xF0000000;
+ #endif    
+ 
+     move_table16[i] = count;
+     i++;
+   }
+ }
+ #else
+ #define init_movetable() ;
+ #endif
+ 
+ extern void
+ init_static_tables()
+ {
+   init_countbits();
+   init_lastbit();
+   init_movetable();
+ }
+ 
+ 
+ KeyInfo      g_keyinfo[2][32][32];
+ 
+ static void
+ negate_keyinfo(KeyInfo_s *keyinfo)
+ {
+   keyinfo->bit1_index = keyinfo->bit2_index = -1;
+   keyinfo->hash_code = 0;
+ }
+ 
+       
+ static void
+ fill_in_hash_code(KeyInfo_s *info, s32bit num_cols)
+ {
+   s32bit r, c, hash = 0;
+     
+   r = info->bit1_index/num_cols;
+   c = info->bit1_index%num_cols;
+   
+   hash = g_zobrist[r+1][c+1];
+   
+   r = info->bit2_index/num_cols;
+   c = info->bit2_index%num_cols;
+   
+   hash ^= g_zobrist[r+1][c+1];
+ 
+   info->hash_code = hash;
+ }
+ 
+ 
+ static void
+ fill_in_key_entry(KeyInfo *keyinfo, s32bit num_rows, s32bit num_cols)
+ {
+   if(keyinfo->norm.bit1_index == -1){
+     negate_keyinfo( & keyinfo->norm);
+     negate_keyinfo( & keyinfo->flipV);
+     negate_keyinfo( & keyinfo->flipH);
+     negate_keyinfo( & keyinfo->flipVH);
+   } else {
+     s32bit r1, c1, r2, c2;
+     
+     r1 = keyinfo->norm.bit1_index/num_cols;
+     c1 = keyinfo->norm.bit1_index%num_cols;
+     r2 = keyinfo->norm.bit2_index/num_cols;
+     c2 = keyinfo->norm.bit2_index%num_cols;
+   
+     keyinfo->flipV.bit1_index  = (r1*num_cols)+(num_cols - c1 - 1);
+     keyinfo->flipV.bit2_index  = (r2*num_cols)+(num_cols - c2 - 1);
+ 
+     keyinfo->flipH.bit1_index  = ((num_rows - r1 - 1) * num_cols) + c1;
+     keyinfo->flipH.bit2_index  = ((num_rows - r2 - 1) * num_cols) + c2;
+ 
+     keyinfo->flipVH.bit1_index = ( ((num_rows - r1 - 1) * num_cols)
+                                    + (num_cols - c1 - 1) );
+     keyinfo->flipVH.bit2_index = ( ((num_rows - r2 - 1) * num_cols)
+                                    + (num_cols - c2 - 1) );
+ 
+     fill_in_hash_code( & keyinfo->norm, num_cols);
+     fill_in_hash_code( & keyinfo->flipV, num_cols);
+     fill_in_hash_code( & keyinfo->flipH, num_cols);
+     fill_in_hash_code( & keyinfo->flipVH, num_cols);
+   }
+ }
+ 
+ 
+ extern void
+ init_less_static_tables()
+ {
+   s32bit n_rows, n_cols, i, j, k;
+   
+   n_rows = g_board_size[HORIZONTAL], n_cols = g_board_size[VERTICAL];
+   
+   for(i = 0; i < 32; i++)
+     for(j = 0; j < 32; j++)
+       for(k = 0; k < 2; k++)
+         negate_keyinfo( & g_keyinfo[k][i][j].norm);
+   
+   for(i = 0; i < n_rows; i++){
+     for(j = 0; j < n_cols; j++){
+       //Horizontal Entry
+       if(j + 1 < n_cols){
+         g_keyinfo[HORIZONTAL][i+1][j+1].norm.bit1_index = (i*n_cols)+j;
+         g_keyinfo[HORIZONTAL][i+1][j+1].norm.bit2_index = (i*n_cols)+(j+1);
+       }
+       
+       //Vertical Entry
+       if(i + 1 < n_rows){
+         g_keyinfo[VERTICAL][j+1][i+1].norm.bit1_index   = (i*n_cols)+j;
+         g_keyinfo[VERTICAL][j+1][i+1].norm.bit2_index   = ((i+1)*n_cols)+j;
+       }
+     }
+   }
+   
+   for(i = 0; i < 32; i++)
+     for(j = 0; j < 32; j++)
+       for(k = 0; k < 2; k++)
+         fill_in_key_entry(&g_keyinfo[k][i][j], n_rows, n_cols);
+ }
+ 


Index: llvm/test/Programs/MultiSource/Applications/obsequi/toggle_move.c
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/toggle_move.c:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/toggle_move.c	Tue May 11 14:34:13 2004
***************
*** 0 ****
--- 1,189 ----
+ 
+ #include "globals.h"
+ #include "macros.h"
+ 
+ //########################################################
+ // This function counts the number of safe moves in a row.
+ //
+ // Never call this function for rows 0 or 31.
+ //########################################################
+ static inline s32bit
+ count_safe(s32bit player, s32bit row)
+ {
+   u32bit guard = g_board[player][row-1] & g_board[player][row+1];
+ 
+   // mask contains a bit for each safe move.
+   u32bit mask= ( (~(g_board[player][row] | (g_board[player][row] << 1)))
+                  & (guard & (guard << 1)) );
+ 
+   return COUNTMOVES(mask);
+ }
+ 
+ //########################################################
+ // This function counts the number of real moves in a row.
+ //
+ // Never call this function for rows 0 or 31.
+ //########################################################
+ static inline s32bit
+ count_real(s32bit player, s32bit row)
+ {
+   // mask contains a bit for each real move.
+   u32bit mask= ~(g_board[player][row] | (g_board[player][row] << 1));
+ 
+   return COUNTMOVES(mask);
+ }
+ 
+ 
+ static inline void
+ _update_safe(s32bit player, s32bit row)
+ {
+   s32bit count = count_safe(player, row);
+ 
+   g_info_totals[player].safe += count - g_info[player][row].safe;
+   g_info[player][row].safe    = count;
+ }
+ 
+ static inline void
+ _update_real(s32bit player, s32bit row)
+ {
+   s32bit count = count_real(player, row);
+   
+   g_info_totals[player].real += count - g_info[player][row].real;
+   g_info[player][row].real = count;
+ }
+ 
+ 
+ 
+ extern void
+ update_safe(s32bit player, s32bit row)
+ { _update_safe(player, row); }
+ 
+ extern void
+ update_real(s32bit player, s32bit row)
+ { _update_real(player, row); }
+ 
+ extern void
+ toggle_move(Move move, s32bit player)
+ {
+   s32bit row, col, horz_play, vert_play;
+   
+   row = (move).array_index, col = (move).mask_index;
+   horz_play = player & PLAYER_MASK;
+   vert_play = player ^ PLAYER_MASK;
+   
+   g_board[horz_play][row]   ^= (3<<col);
+   g_board[vert_play][col]   ^= (1<<row);
+   g_board[vert_play][col+1] ^= (1<<row);
+   
+   // update safe moves
+   if(row - 1 != 0)
+     _update_safe(horz_play, row - 1);
+   _update_safe(horz_play, row);
+   if(row != g_board_size[horz_play])
+     _update_safe(horz_play, row + 1);
+   
+   if(col - 1 != 0)
+     _update_safe(vert_play, col - 1);
+   if(col + 1 != g_board_size[vert_play])
+     _update_safe(vert_play, col + 2);
+   
+   // update real moves
+   _update_real(horz_play, row);
+ 
+   _update_real(vert_play, col);
+   _update_real(vert_play, col + 1);
+ }
+ 
+ 
+ //#define DEBUG_SCORE_MOVE
+ 
+ static inline s32bit
+ score_move(Move move, s32bit player)
+ {
+   s32bit row, col, horz_play, vert_play;
+   s32bit score;
+     
+   row = move.array_index, col = move.mask_index;
+   horz_play = player & PLAYER_MASK;
+   vert_play = player ^ PLAYER_MASK;
+   
+   g_board[horz_play][row]   ^= (3<<col);
+   g_board[vert_play][col]   ^= (1<<row);
+   g_board[vert_play][col+1] ^= (1<<row);
+   
+   // update real moves
+   score = count_real(horz_play, row) - g_info[horz_play][row].real;
+ 
+   score -= count_real(vert_play, col) - g_info[vert_play][col].real;
+   score -= count_real(vert_play, col + 1) - g_info[vert_play][col+1].real;
+ 
+   // update safe moves
+   if(row - 1 != 0)
+     score +=  count_safe(horz_play, row - 1) - g_info[horz_play][row-1].safe;
+   score += count_safe(horz_play, row) - g_info[horz_play][row].safe;
+   if(row != g_board_size[horz_play])
+     score += count_safe(horz_play, row+1) - g_info[horz_play][row+1].safe;
+   
+   if(col - 1 != 0)
+     score -= count_safe(vert_play, col - 1) - g_info[vert_play][col-1].safe;
+   if(col + 1 != g_board_size[vert_play])
+     score -= count_safe(vert_play, col + 2) - g_info[vert_play][col+2].safe;
+   
+   g_board[horz_play][row]   ^= (3<<col);
+   g_board[vert_play][col]   ^= (1<<row);
+   g_board[vert_play][col+1] ^= (1<<row);
+   
+   score *= 128;
+   score += g_first_move[player][row][col];
+ 
+   return score;
+ }
+ 
+ extern void
+ score_and_get_first(Move movelist[MAXMOVES], s32bit num_moves,
+                     s32bit player, Move first)
+ {
+   s32bit i, max = -50000, max_index = -1;
+ 
+   //========================================================
+   // Give the move from the hashtable a large sorting value.
+   //========================================================
+   /*
+   {
+     int z = 0;
+     for (z = 0; z < num_moves; z++)
+       printf("> %d %d\n", movelist[z].array_index, movelist[z].mask_index);
+   }
+   */
+   if(first.array_index != -1){
+     for(i = 0; i < num_moves; i++){
+       if(first.array_index == movelist[i].array_index
+          && first.mask_index == movelist[i].mask_index){
+         movelist[i].info = 450000;
+         max_index = i;
+       } else {
+         movelist[i].info = score_move(movelist[i], player);
+       }
+     }
+   }
+ 
+   else {
+     for(i = 0; i < num_moves; i++){
+       movelist[i].info = score_move(movelist[i], player);
+       if(movelist[i].info > max){
+         max = movelist[i].info;
+         max_index = i;
+       }
+     }
+   }
+   
+   if(max_index == -1) fatal_error(1, "No maximum\n");
+   
+   // put biggest at front
+   if(num_moves > 1) {
+     Move tmp_move = movelist[max_index];
+     for(i = max_index; i > 0; i--)
+       movelist[i] = movelist[i - 1];
+     movelist[0] = tmp_move;
+   }
+ }


Index: llvm/test/Programs/MultiSource/Applications/obsequi/traits.c
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/traits.c:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/traits.c	Tue May 11 14:34:13 2004
***************
*** 0 ****
--- 1,174 ----
+ 
+ #include "globals.h"
+ #include "macros.h"
+ 
+ static FILE *trait_file = NULL;
+ 
+ 
+ static s32bit
+ tr_total_non_safe_moves(s32bit player)
+ {
+   u32bit mask1, mask2;
+   s32bit num_rows = g_board_size[player];
+   s32bit count = 0, i;
+   
+   for(i = 0; i < num_rows; i++){
+     mask1 = g_board[player][i] & g_board[player][i+2];
+     mask2 = ~g_board[player][i+1];
+     
+     mask1 = (~((mask1 >> 1) & mask1)) & ((mask2 >> 1) & mask2);
+ 
+     //    printf("%X\n", mask1);
+     
+     count += countbits32(mask1);
+   }
+   
+   return count;
+ }
+ 
+ static s32bit
+ tr_non_safe_moves_a_little_touchy(s32bit player)
+ {
+   u32bit mask1, mask2;
+   s32bit num_rows = g_board_size[player];
+   s32bit count = 0, i;
+   
+   for(i = 0; i < num_rows; i++){
+     mask1 = g_board[player][i] | g_board[player][i+2];
+     mask2 = g_board[player][i+1];
+     
+     mask1 = ( (mask1 << 1) | mask1
+               | (mask2 >> 1) | mask2 | (mask2 << 1) | (mask2 << 2) );
+ 
+     count += countbits32(~mask1);
+   }
+ 
+   if(count == -1){
+     print_board(player);
+     printf("%d %d\n", player, count);
+     exit(1);
+   }
+   
+   return count;
+ }
+ 
+ static s32bit
+ tr_non_safe_moves_no_touchy(s32bit player)
+ {
+   return 1;
+ }
+ 
+ static s32bit
+ tr_total_empty_squares()
+ {
+   u32bit mask;
+   s32bit num_rows = g_board_size[0];
+   s32bit count = 0, i;
+   
+   for(i = 0; i < num_rows; i++){
+     mask = ~(g_board[0][i+1]);
+ 
+     count += countbits32(mask);
+   }
+     
+   return count;
+ }
+ 
+ static s32bit
+ tr_border_length_col(player)
+ {
+   u32bit mask;
+   s32bit num_rows = g_board_size[player];
+   s32bit count = 0, i;
+   
+   for(i = 0; i <= num_rows; i++){
+     mask = g_board[player][i] ^ g_board[player][i+1];
+ 
+     count += countbits32(mask);
+   }
+   
+   return count;
+ }
+ 
+ static s32bit
+ tr_border_length_row(player)
+ {
+   u32bit mask;
+   s32bit num_rows = g_board_size[player];
+   s32bit count = 0, i;
+   
+   for(i = 0; i <= num_rows; i++){
+     mask  = (g_board[player][i+1]>>1) ^ g_board[player][i+1];
+     mask &= 0x7FFFFFFF;
+     
+     count += countbits32(mask);
+   }
+   
+   return count;
+ }
+ 
+ 
+ 
+ 
+ extern void
+ write_node_info(u64bit num_nodes, s32bit winner)
+ {
+   s32bit num;
+   
+   if(trait_file == NULL) {
+     trait_file = fopen("trait_file", "w");
+     if(trait_file == NULL)
+       fprintf(stderr, "Couldn't open \"trait_file\".\n");
+   }
+   
+   fprintf(trait_file, "%c %15s :", (winner == VERTICAL) ? 'V' : 'H',
+           u64bit_to_string(num_nodes));
+   
+   //========================================================
+   // number of non-safe moves.
+   //========================================================
+   
+   // total number allowing overlapping of other non-safe moves
+   //   and of safe moves.
+   num = tr_total_non_safe_moves(winner);
+   fprintf(trait_file, " %2d", num);
+ 
+   num = tr_total_non_safe_moves(winner^PLAYER_MASK);
+   fprintf(trait_file, " %2d :", num);
+   
+   
+   // non safe moves that don't touch a border, except diagonally.
+   num = tr_non_safe_moves_a_little_touchy(winner);
+   fprintf(trait_file, " %2d", num);
+ 
+   num = tr_non_safe_moves_a_little_touchy(winner^PLAYER_MASK);
+   fprintf(trait_file, " %2d :", num);
+ 
+ 
+   // non safe moves that don't touch a border, never.
+   num = tr_non_safe_moves_no_touchy(winner);
+   fprintf(trait_file, " %2d", num);
+ 
+   num = tr_non_safe_moves_no_touchy(winner^PLAYER_MASK);
+   fprintf(trait_file, " %2d :", num);
+ 
+ 
+   //========================================================
+   // Miscellaneous other info.
+   //========================================================
+ 
+   // empty squares.
+   num = tr_total_empty_squares();
+   fprintf(trait_file, " %2d :", num);
+ 
+   // border length.
+   num = tr_border_length_col(winner);
+   fprintf(trait_file, " %2d", num);
+ 
+   // border length.
+   num = tr_border_length_row(winner);
+   fprintf(trait_file, " %2d", num);
+ 
+   fprintf(trait_file, "\n");
+ }
+ 


Index: llvm/test/Programs/MultiSource/Applications/obsequi/utils.c
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/utils.c:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/utils.c	Tue May 11 14:34:13 2004
***************
*** 0 ****
--- 1,163 ----
+ 
+ #include "utils.h"
+ 
+ #include <stdarg.h>
+ #include <ctype.h>
+ #include <sys/stat.h>
+ #include <sys/types.h>
+ #include <sys/wait.h>
+ #include <unistd.h>
+ #include <stdarg.h>
+ #include <regex.h>
+ 
+ 
+ //########################################################
+ // This function prints a message to both stderr and
+ //   to the file ".fatal_error".
+ //
+ // If ERR_NUM != 0 then exit is called with the value ERR_NUM.
+ //########################################################
+ extern void
+ _fatal_error_aux(const char *file, const s32bit line, const s32bit err_num,
+                  const char *format, ... )
+ {
+   va_list ap;
+   static FILE* err_file = NULL;
+   char *msg_type = (err_num == 0) ? "WARNING: " : "ERROR: ";
+ 
+   // only need to open this if not already open.
+   if(err_file == NULL)  err_file = fopen(".fatal_error", "w");
+   if(err_file == NULL) fprintf(stderr, "Couldn't open \".fatal_error\".\n");
+   
+   if(err_num == 0) {
+     // Check size of file, we don't want to end up filling up the whole disk.
+     s32bit size = ftell(err_file);
+     if(size == -1)
+       fatal_error(1, "size == -1.\n");
+     
+     else if(size > (2<<24) + 2000 ){
+       return;
+     }
+     
+     else if(size > (2<<24)){
+       fprintf(stderr, "Log file getting too large.\n");
+       fprintf(err_file, "Log file getting too large.\n");
+     }
+   }
+   
+   // start writing the real message.
+   fprintf(stderr, msg_type);
+   fprintf(err_file, msg_type);
+   
+   va_start (ap, format);
+   vfprintf (stderr, format, ap);
+   vfprintf (err_file, format, ap);
+   va_end (ap);
+   
+   fprintf(stderr, "> File: %s, Line: %d.\n", file, line);
+   fprintf(err_file, "> File: %s, Line: %d.\n", file, line);
+ 
+   fflush(stderr);
+   fflush(err_file);
+     
+   if (err_num != 0)  exit(err_num);
+ }
+ 
+ 
+ //########################################################
+ // These are dynamic sprintf function, they malloc space as needed.
+ //########################################################
+ 
+ //========================================================
+ // This function stores the string created from FORMAT and the
+ //   following args to the string STR, starting at position OFFSET.
+ //========================================================
+ extern s32bit
+ Asprintf(char **str, s32bit *len, s32bit offset, const char *format, ... )
+ {
+   va_list ap;
+   s32bit nchars;
+   
+   va_start (ap, format);
+ 
+   // if no space allocated yet, allocate some.
+   if(*len == 0){ *len = 128; *str = malloc(*len); }
+   
+   while (1) {
+     // attempt printing in the allocated space
+     nchars = vsnprintf (*str + offset, *len - offset, format, ap);
+         
+     if (nchars < *len - offset) break;
+     
+     // if not enough space allocate some more.
+     *len += 128;
+     *str = realloc(*str, *len);
+   }
+   
+   va_end (ap);
+   return nchars;
+ }
+ 
+ //========================================================
+ // This function stores the string created from FORMAT and the
+ //   following args to the end of the string STR.
+ //========================================================
+ extern s32bit
+ asprintf_my(char **str, s32bit offset, const char *format, ... )
+ {
+   va_list ap;
+   s32bit nchars, len = ALLOCED(*str,char);
+   
+   va_start (ap, format);
+ 
+   // if no space allocated yet, allocate some.
+   if(len == 0){ len = 128; *str = malloc(len); }
+   
+   while (1) {
+     // attempt printing in the allocated space
+     nchars = vsnprintf (*str + offset, len - offset, format, ap);
+         
+     if (nchars < len - offset) break;
+     
+     // if not enough space allocate some more.
+     len += 128;
+     *str = realloc(*str, len);
+   }
+   
+   va_end (ap);
+   return nchars;
+ }
+ 
+ 
+ //########################################################
+ // Return a string with the printed value of a 64 bit number.
+ //########################################################
+ extern const char*
+ u64bit_to_string(u64bit val)
+ {
+   static char   big_num[80];    // plenty large
+   s32bit        vals[10];       // plenty large
+   s32bit        i = 0, offset;
+   
+   do {
+     vals[i] = val % 1000;
+     val = val / 1000;
+     i++;
+   } while(val != 0);
+   
+   offset = sprintf(big_num, "%d", vals[--i]);
+   
+   while(i != 0)
+     offset += sprintf(big_num + offset, ",%03d", vals[--i]);
+   
+   return big_num;
+ }
+ 
+ 
+ //########################################################
+ // I'm not sure why I have this function.
+ //  I suppose it may come in useful for performance analysis.
+ //########################################################
+ extern void
+ null_command() {}
+ 


Index: llvm/test/Programs/MultiSource/Applications/obsequi/utils.h
diff -c /dev/null llvm/test/Programs/MultiSource/Applications/obsequi/utils.h:1.1
*** /dev/null	Tue May 11 14:34:23 2004
--- llvm/test/Programs/MultiSource/Applications/obsequi/utils.h	Tue May 11 14:34:13 2004
***************
*** 0 ****
--- 1,143 ----
+ 
+ 
+ #ifndef OBSEQUI_UTILS_H
+ #define OBSEQUI_UTILS_H
+ 
+ #define _GNU_SOURCE  //Need this so that __USE_GNU is defined
+ #include <features.h>
+ 
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <malloc.h>
+ #include <string.h>
+ 
+ 
+ //#################################################################
+ // Define a couple of types which I like to use.
+ //#################################################################
+ 
+ typedef  u_int8_t   u8bit;
+ typedef  u_int16_t  u16bit;
+ typedef  u_int32_t  u32bit;
+ typedef  u_int64_t  u64bit;
+ 
+ typedef  int16_t    s16bit;
+ typedef  int32_t    s32bit;
+ 
+ 
+ //#################################################################
+ // Define a number of useful constants and macros.
+ //#################################################################
+ 
+ //=================================================================
+ // I think that DEFINED should always be defined.
+ // Also make sure NOT_DEFINED is not.
+ //=================================================================
+ #define DEFINED
+ #undef  NOT_DEFINED
+ 
+ //=================================================================
+ // Determine the max value of two numbers.
+ //=================================================================
+ #define MAX_TWO(a,b) (((a) > (b)) ? (a) : (b))
+ 
+ //=================================================================
+ // Determine the min value of two numbers.
+ //=================================================================
+ #define MIN_TWO(a,b) (((a) > (b)) ? (b) : (a))
+ 
+ //=================================================================
+ // Constants and Macros for dealing with bit masks.
+ //=================================================================
+ #define ALL_BITS         0xFFFFFFFF
+ #define NTH_BIT(i)       ( 1 << (i) )
+ #define FIRST_N_BITS(i)  (~(ALL_BITS << (i)))
+ #define LAST_N_BITS(i)   (~(ALL_BITS >> (i)))
+ 
+ //=================================================================
+ // Determine how many elements have been alloced for ptr.
+ //  - this probably only works if using glibc.
+ //=================================================================
+ #define ALLOCED(ptr,type) (malloc_usable_size(ptr)/sizeof(type))
+ 
+ 
+ //########################################################
+ // The following functions print a message to both stderr and
+ //   to the file ".fatal_error". These messages can be helpful
+ //   for debugging since they contain both the file name and line number
+ //   of where this function was called. (They all return void.)
+ //########################################################
+ 
+ //========================================================
+ // Besides printing a message this function also causes the
+ //   program to exit with the value 'err_num'.
+ //========================================================
+ #define fatal_error(err_num, format, rest...) \
+          (_fatal_error((err_num) ? (err_num) : 256, format, ## rest ))
+ 
+ //========================================================
+ // This function justs prints the message.
+ //========================================================
+ #define warning(format, rest...) \
+          (_fatal_error(0, format, ## rest ))
+ 
+ //========================================================
+ // This function prints the message "Check Point."
+ //   Exclusively used for debugging.
+ //========================================================
+ #define check_point() \
+          (_fatal_error(0, "Check Point.\n"))
+ 
+ 
+ #define _fatal_error(err_num, format, rest...) \
+          (_fatal_error_aux(__FILE__, __LINE__, (err_num), format, ## rest ))
+ 
+ 
+ //########################################################
+ // These are dynamic sprintf function, they malloc space as needed.
+ //########################################################
+ 
+ //========================================================
+ // stores the string created from FORMAT, and ..., in *str.
+ //
+ // allocates space as needed.
+ // returns the number of characters written to *str.
+ //========================================================
+ extern s32bit
+ Asprintf(char **str, s32bit *len, s32bit offset, const char *format, ... )
+      __attribute__ ((format (printf, 4, 5)));
+ 
+ //========================================================
+ // returns the number of characters written to *(str+offset)
+ //========================================================
+ extern s32bit
+ asprintf_my(char **str, s32bit offset, const char *format, ... )
+      __attribute__ ((format (printf, 3, 4)));
+ 
+ 
+ 
+ //########################################################
+ // This function does absolutely nothing.
+ //########################################################
+ extern void
+ null_command();
+ 
+ 
+ //########################################################
+ // Return a string with the printed value of a 64 bit number.
+ // Note: It returns a static buffer so don't free it, and
+ //       always copy the value before you call it again.
+ //########################################################
+ extern const char*
+ u64bit_to_string(u64bit val);
+ 
+ 
+ //########################################################
+ // Internals.
+ //########################################################
+ extern void
+ _fatal_error_aux(const char *file, const s32bit line,
+                  const s32bit err_num, const char *format, ... )
+      __attribute__ ((format (printf, 4, 5)));
+      
+ #endif





More information about the llvm-commits mailing list