/gamazons-0.83/src/moves.c
C | 2203 lines | 1589 code | 300 blank | 314 comment | 260 complexity | 7a655390de8a7fa1943b91b60e16bd79 MD5 | raw file
Possible License(s): GPL-2.0
- /*************
- sean mcmillen
- ronald yorgason
- CS410 Combinatorial Games -- Spring 2002
- amazons player.
- amazons -h for options
- Project URL: http://www.yorgalily.org/amazons/
- ***************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <limits.h>
- #include <time.h>
- #include <assert.h>
- #include <ctype.h>
- #include <sys/poll.h>
- //#ifdef GAMAZONS
- #include <gnome.h>
- //#endif
- #include "amazons.h"
- #include "unit-test.h"
- #define HEVAL heval // for testing differant hevals
- #define MINDEPTH 1
- #define VERBOSE 0
- #define TIMED 1 // boolean, if 1 then TIMEOUT is in effect, if 0 then no
- // macros
- //#define MIN(a,b) (a < b ? a : b)
- //#define MAX(a,b) (a > b ? a : b)
- #define MMSET(p,q) ((p) == 1 ? SHRT_MIN+q : SHRT_MAX-q)
- // constants
- #define WHITEQUEENS 4
- #define BLACKQUEENS 4
- /* local prototypes */
- move mtdf(state *s, int guess, int tdepth);
- // some globals //
- FILE *movin; // read moves from here
- FILE *movout; // write moves to here
- struct pollfd pollstruct; // used to poll FILE *movin
- int onmove;
- int nodes; // statitics gatherer
- int rawnodes; // statitics gatherer
- int hevalz; // statitics gatherer
- int hits; // statitics gatherer
- int ok; // global, if 0 then timeout condition
- time_t start; // global, start of search, used for timeout
- // check
- struct options options;
- struct game_states states;
- #ifdef GAMAZONS
- extern int state_hash;
- extern GtkWidget *main_window;
- #endif
- // command line flags -- set defaults here
- /*
- int white_player = FALSE;
- int black_player = FALSE;
- int print_statistics = FALSE;
- int TIMEOUT = 5;
- int MAXDEPTH = 20;
- int MAXWIDTH = 5000;
- */
- int obst_heval(state *s)
- {
- int moves;
- int t1;
- int t2;
- int turn;
- if (onmove > 10)
- return heval(s);
- turn = s->turn;
- s->turn = WHITE_PLAYER;
- t1 = countobst(s);
- s->turn = BLACK_PLAYER;
- t2 = countobst(s);
- s->turn = turn;
- moves = t1 - t2;
- return moves;
- }
- int countobst(state *s)
- {
- int i,j;
- int m=0, p=0;
- int xo=0, yo=0;
- int axo=0, ayo=0;
- int dir, adir;
- int QUEENS;
- uchar *queens_x;
- uchar *queens_y;
- ull *board;
- int queen = 0;
- if(s->turn == WHITE_PLAYER)
- {
- queens_x = s->white_q_x;
- queens_y = s->white_q_y;
- board = s->white_bd;
- QUEENS = WHITEQUEENS;
- }
- else
- {
- queens_x = s->black_q_x;
- queens_y = s->black_q_y;
- board = s->black_bd;
- QUEENS = BLACKQUEENS;
- }
- // order: N NE E SE S SW W NW
- for (queen = 0; queen < QUEENS; queen++)
- {
- for (dir = 0; dir < 8; dir++)
- {
- // for tightness not speed
- switch (dir)
- {
- case 0:
- xo = 0; yo = 1;
- break;
- case 1:
- xo = 1; yo = 1;
- break;
- case 2:
- xo = 1; yo = 0;
- break;
- case 3:
- xo = 1; yo = -1;
- break;
- case 4:
- xo = 0; yo = -1;
- break;
- case 5:
- xo = -1; yo = -1;
- break;
- case 6:
- xo = -1; yo = 0;
- break;
- case 7:
- xo = -1; yo = 1;
- break;
- }
- for (i=1; i < 10; i++)
- {
- // out of bounds
- if (queens_x[queen] + xo*i > 9 ||
- queens_y[queen] + yo*i > 9 ||
- queens_x[queen] + xo*i < 0 ||
- queens_y[queen] + yo*i < 0)
- {
- // count obst
- for (adir = 0; adir < 8; adir++)
- {
- // for tightness not speed
- switch (adir)
- {
- case 0:
- axo = 0; ayo = 1;
- break;
- case 1:
- axo = 1; ayo = 1;
- break;
- case 2:
- axo = 1; ayo = 0;
- break;
- case 3:
- axo = 1; ayo = -1;
- break;
- case 4:
- axo = 0; ayo = -1;
- break;
- case 5:
- axo = -1; ayo = -1;
- break;
- case 6:
- axo = -1; ayo = 0;
- break;
- case 7:
- axo = -1; ayo = 1;
- break;
- }
- if (dir == adir) continue;
- for (j=1; j < 2; j++)
- {
- if (queens_x[queen] + axo*j > 9 ||
- queens_y[queen] + ayo*j > 9 ||
- queens_x[queen] + axo*j < 0 ||
- queens_y[queen] + ayo*j < 0)
- {
- break;
- }
- if (test(s, queens_x[queen]+axo*j,
- queens_y[queen]+ayo*j))
- {
- break;
- }
- m+=1;
- }
- }
- break;
- }
- // hit a wall
- if (test(s, queens_x[queen]+xo*i, queens_y[queen]+yo*i))
- {
- for (adir = 0; adir < 8; adir++)
- {
- // for tightness not speed
- switch (adir)
- {
- case 0:
- axo = 0; ayo = 1;
- break;
- case 1:
- axo = 1; ayo = 1;
- break;
- case 2:
- axo = 1; ayo = 0;
- break;
- case 3:
- axo = 1; ayo = -1;
- break;
- case 4:
- axo = 0; ayo = -1;
- break;
- case 5:
- axo = -1; ayo = -1;
- break;
- case 6:
- axo = -1; ayo = 0;
- break;
- case 7:
- axo = -1; ayo = 1;
- break;
- }
- //if (dir == adir) continue;
- if (dir == adir) continue;
- for (j=1; j < 2; j++)
- {
- if (queens_x[queen] + axo*j > 9 ||
- queens_y[queen] + ayo*j > 9 ||
- queens_x[queen] + axo*j < 0 ||
- queens_y[queen] + ayo*j < 0)
- {
- break;
- }
- if (test(s, queens_x[queen]+axo*j,
- queens_y[queen]+ayo*j))
- {
- break;
- }
- m+=1;
- }
- }
- break;
- }
- m+=2;
- /*
- xor(board, queens_x[queen], queens_y[queen]);
- queens_x[queen] += i*xo;
- queens_y[queen] += i*yo;
- xor(board, queens_x[queen], queens_y[queen]);
- // look for arrow moves.
- // order: N NE E SE S SW W NW
- xor(board, queens_x[queen], queens_y[queen]);
- queens_x[queen] -= i*xo;
- queens_y[queen] -= i*yo;
- xor(board, queens_x[queen], queens_y[queen]);
- */
- }
- }
- }
- return m;
- }
- // heuristic function
- int sean_heval(state *s)
- {
- int moves;
- int t1;
- int t2;
- int turn;
- turn = s->turn;
- s->turn = WHITE_PLAYER;
- t1 = countchildren(s);
- s->turn = BLACK_PLAYER;
- t2 = countchildren(s);
- s->turn = turn;
- moves = t1 - t2;
- return moves;
- }
- int countchildren(state *s)
- {
- int i,j;
- int m=0;
- int xo=0, yo=0;
- int axo=0, ayo=0;
- int dir, adir;
- int QUEENS;
- uchar *queens_x;
- uchar *queens_y;
- ull *board;
- int queen = 0;
- if(s->turn == WHITE_PLAYER)
- {
- queens_x = s->white_q_x;
- queens_y = s->white_q_y;
- board = s->white_bd;
- QUEENS = WHITEQUEENS;
- }
- else
- {
- queens_x = s->black_q_x;
- queens_y = s->black_q_y;
- board = s->black_bd;
- QUEENS = BLACKQUEENS;
- }
- // look for moves.
- // order: N NE E SE S SW W NW
- // this loop moves a queen, shoots an arrow, all the while
- // checking to see if its run into things.
- // populated movelist (passing in as reference) with the valid moves.
- for (queen = 0; queen < QUEENS; queen++)
- {
- for (dir = 0; dir < 8; dir++)
- {
- // for tightness not speed
- switch (dir)
- {
- case 0:
- xo = 0; yo = 1;
- break;
- case 1:
- xo = 1; yo = 1;
- break;
- case 2:
- xo = 1; yo = 0;
- break;
- case 3:
- xo = 1; yo = -1;
- break;
- case 4:
- xo = 0; yo = -1;
- break;
- case 5:
- xo = -1; yo = -1;
- break;
- case 6:
- xo = -1; yo = 0;
- break;
- case 7:
- xo = -1; yo = 1;
- break;
- }
- for (i=1; i < 10; i++)
- {
- // out of bounds
- if (queens_x[queen] + xo*i > 9 ||
- queens_y[queen] + yo*i > 9 ||
- queens_x[queen] + xo*i < 0 ||
- queens_y[queen] + yo*i < 0)
- {
- break;
- }
- // hit a wall
- if (test(s, queens_x[queen]+xo*i, queens_y[queen]+yo*i))
- {
- break;
- }
- xor(board, queens_x[queen], queens_y[queen]);
- queens_x[queen] += i*xo;
- queens_y[queen] += i*yo;
- xor(board, queens_x[queen], queens_y[queen]);
- // look for arrow moves.
- // order: N NE E SE S SW W NW
- for (adir = 0; adir < 8; adir++)
- {
- // for tightness not speed
- switch (adir)
- {
- case 0:
- axo = 0; ayo = 1;
- break;
- case 1:
- axo = 1; ayo = 1;
- break;
- case 2:
- axo = 1; ayo = 0;
- break;
- case 3:
- axo = 1; ayo = -1;
- break;
- case 4:
- axo = 0; ayo = -1;
- break;
- case 5:
- axo = -1; ayo = -1;
- break;
- case 6:
- axo = -1; ayo = 0;
- break;
- case 7:
- axo = -1; ayo = 1;
- break;
- }
- for (j=1; j < 10; j++)
- {
- if (queens_x[queen] + axo*j > 9 ||
- queens_y[queen] + ayo*j > 9 ||
- queens_x[queen] + axo*j < 0 ||
- queens_y[queen] + ayo*j < 0)
- {
- break;
- }
- if (test(s, queens_x[queen]+axo*j,
- queens_y[queen]+ayo*j))
- {
- break;
- }
- // put arrow
- m++;
- }
- }
- xor(board, queens_x[queen], queens_y[queen]);
- queens_x[queen] -= i*xo;
- queens_y[queen] -= i*yo;
- xor(board, queens_x[queen], queens_y[queen]);
- }
- }
- }
- return m;
- }
- // populates movelist[] with all possible moves.
- // returns the count of moves
- // the value of the move is also set here, that means
- // this is the function that calls heval (heuristic)
- // and tt_lookup (transposition table retrieve)
- int children(state *s, move movelist[])
- {
- int i,j;
- int m=0;
- int xo=0, yo=0;
- int axo=0, ayo=0;
- int dir, adir;
- int QUEENS;
- uchar *queens_x;
- uchar *queens_y;
- ull *board;
- int queen = 0;
- if(s->turn == WHITE_PLAYER)
- {
- queens_x = s->white_q_x;
- queens_y = s->white_q_y;
- board = s->white_bd;
- QUEENS = WHITEQUEENS;
- }
- else
- {
- queens_x = s->black_q_x;
- queens_y = s->black_q_y;
- board = s->black_bd;
- QUEENS = BLACKQUEENS;
- }
- // look for moves.
- // order: N NE E SE S SW W NW
- // this loop moves a queen, shoots an arrow, all the while
- // checking to see if its run into things.
- // populated movelist (passing in as reference) with the valid moves.
- for (queen = 0; queen < QUEENS; queen++)
- {
- for (dir = 0; dir < 8; dir++)
- {
- // for tightness not speed
- switch (dir)
- {
- case 0:
- xo = 0; yo = 1;
- break;
- case 1:
- xo = 1; yo = 1;
- break;
- case 2:
- xo = 1; yo = 0;
- break;
- case 3:
- xo = 1; yo = -1;
- break;
- case 4:
- xo = 0; yo = -1;
- break;
- case 5:
- xo = -1; yo = -1;
- break;
- case 6:
- xo = -1; yo = 0;
- break;
- case 7:
- xo = -1; yo = 1;
- break;
- }
- for (i=1; i < 10; i++)
- {
- // out of bounds
- if (queens_x[queen] + xo*i > 9 ||
- queens_y[queen] + yo*i > 9 ||
- queens_x[queen] + xo*i < 0 ||
- queens_y[queen] + yo*i < 0)
- {
- break;
- }
- // hit a wall
- if (test(s, queens_x[queen]+xo*i, queens_y[queen]+yo*i))
- {
- break;
- }
- xor(board, queens_x[queen], queens_y[queen]);
- queens_x[queen] += i*xo;
- queens_y[queen] += i*yo;
- xor(board, queens_x[queen], queens_y[queen]);
- // look for arrow moves.
- // order: N NE E SE S SW W NW
- for (adir = 0; adir < 8; adir++)
- {
- // for tightness not speed
- switch (adir)
- {
- case 0:
- axo = 0; ayo = 1;
- break;
- case 1:
- axo = 1; ayo = 1;
- break;
- case 2:
- axo = 1; ayo = 0;
- break;
- case 3:
- axo = 1; ayo = -1;
- break;
- case 4:
- axo = 0; ayo = -1;
- break;
- case 5:
- axo = -1; ayo = -1;
- break;
- case 6:
- axo = -1; ayo = 0;
- break;
- case 7:
- axo = -1; ayo = 1;
- break;
- }
- for (j=1; j < 10; j++)
- {
- if (queens_x[queen] + axo*j > 9 ||
- queens_y[queen] + ayo*j > 9 ||
- queens_x[queen] + axo*j < 0 ||
- queens_y[queen] + ayo*j < 0)
- {
- break;
- }
- if (test(s, queens_x[queen]+axo*j,
- queens_y[queen]+ayo*j))
- {
- break;
- }
- /*
- // put arrow
- xor(s->blocks_bd, queens_x[queen]+axo*j, queens_y[queen]+ayo*j);
- s->turn ^= 3;
- // printf("evaluating board:");
- // pboard(*s);
- if ((stt = tt_lookup(s)))
- {
- //tt_yes++;
- hits++;
- movelist[m].val = stt->value;
- movelist[m].depth = stt->depth;
- }
- else
- {
- //tt_no++;
- movelist[m].val = HEVAL(s);
- hevalz++;
- s->value = movelist[m].val;
- s->depth = 1;
- tt_store(s, SHRT_MIN, SHRT_MAX);
- }
- // remove arrow
- xor(s->blocks_bd, queens_x[queen]+axo*j, queens_y[queen]+ayo*j);
- s->turn ^= 3;
- */
- movelist[m].queen=queen;
- movelist[m].tocol=queens_x[queen];
- movelist[m].torow=queens_y[queen];
- movelist[m].wallcol=queens_x[queen]+axo*j;
- movelist[m].wallrow=queens_y[queen]+ayo*j;
- // pmove(movelist[m]);
- // printf("\n");
- m++;
- }
- }
- xor(board, queens_x[queen], queens_y[queen]);
- queens_x[queen] -= i*xo;
- queens_y[queen] -= i*yo;
- xor(board, queens_x[queen], queens_y[queen]);
- }
- }
- }
- return m;
- }
- // for qsort
- int mincompare(move *m1, move *m2) // USED BY MAXIMIZER
- {
- if (m1->val > m2->val)
- return -1;
- else if (m1->val < m2->val)
- return 1;
- return 0;
- }
- // for qsort
- int maxcompare(move *m1, move *m2)
- {
- if (m1->val < m2->val)
- return -1;
- else if (m1->val > m2->val)
- return 1;
- return 0;
- }
- // top level iterative search function. called from main, pretty
- // self explanatory
- move isearch(state *s, int think)
- {
- int i;
- move temp1, temp2;
- move even, odd;
- int temp2_valid = FALSE;
- even.val = 0;
- odd.val = 0;
- for (i=MINDEPTH; i <= options.engine.maxdepth; i++)
- {
- rawnodes = 0;
- nodes = 0;
- hits = 0;
- hevalz =0;
- temp1 = search(s, 0, SHRT_MIN, SHRT_MAX, i, think);
- /*
- // for mtdf NOT WORKING CURRENTLY
- if (i & 1)
- {
- temp1 = mtdf(s, odd.val, i);
- even = temp1;
- }
- else
- {
- temp1 = mtdf(s, even.val, i);
- odd = temp1;
- }
- */
- //printf("Searched to depth %d, %d cache hits of %d lookups. %d nodes searched.\n", i,hits,rawnodes, nodes);
- //printf("hevals = %d\n", hevalz);
- if (ok) // using this global ok is pretty sloppy but works.
- {
- temp2 = temp1;
- temp2_valid = TRUE;
- }
- else
- {
- if (think)
- {
- #ifdef DEBUG
- printf("searched %d nodes on your time\n", nodes);
- #endif
- }
- #ifdef DEBUG
- printf("time's up at depth %d\n", i);
- #endif
- break;
- }
- }
- if (temp2_valid)
- return temp2;
- else
- return temp1;
- }
- // NOT WORKING
- move mtdf(state *s, int guess, int tdepth)
- {
- move temp;
- //int f;
- int lowerbound = SHRT_MIN;
- int upperbound = SHRT_MAX;
- int beta;
- temp.val = guess;
- do
- {
- if (temp.val == lowerbound)
- {
- beta = temp.val + 1;
- }
- else
- {
- beta = temp.val;
- }
- //temp = search(s, 0, beta - 1, beta, tdepth, think);
- if (temp.val < beta)
- {
- upperbound = temp.val;
- }
- else
- {
- lowerbound = temp.val;
- }
- }
- while (!(lowerbound >= upperbound));
- return temp;
- }
- // minimax search.
- // tdepth is "target depth", that is the current iterative target level
- move search(state *s, int depth, int alpha, int beta, int tdepth, int think)
- {
- state_t *stt;
- move movelist[3000];
- int i;
- int index=0;
- move stemp;
- move temp;
- int randomizer;
- // int tt_yes=0;
- // int tt_no=0;
- int movecount;
- int done;
- nodes++;
- if ((time_t)time(NULL) - start > options.engine.timeout && TIMED && !think)
- {
- ok = 0;
- return movelist[0];
- }
- if (think)
- {
- if (poll(&pollstruct, 1, 0))
- {
- ok = 0;
- return movelist[0];
- }
- }
- movecount = children(s, movelist);
- if (movecount == 0) // no more moves
- {
- if (depth == 0)
- {
- #ifdef DEBUG
- printf("player %d wins!\n", s->turn^3);
- #endif
- s->winner = s->turn^3;
- if (options.print_statistics)
- print_stats();
- #ifndef GAMAZONS
- exit(1);
- #endif
- }
- // if no more moves, then set the value here to
- // a very high value plus/minus the depth
- // this ensure that the loser will select the longest path
- // to loss, and the winner will select the shortest path to
- // a win.
- movelist[0].val = MMSET(s->turn, depth);
- }
- // for node reordering, make sure everything has a value.
- for (i=0; i <movecount; i++)
- {
- #ifdef GAMAZONS
- //Make the game responsive while the AI is thinking
- while (gtk_events_pending())
- gtk_main_iteration();
- #endif
- temp = savemove(s, movelist[i]);
- makemove(s, movelist[i]);
- if ((stt = tt_lookup(s)))
- {
- if (alpha >= stt->alpha && beta <= stt->beta) // correct
- {
- hits++;
- movelist[i].val = stt->value;
- movelist[i].depth = stt->depth;
- }
- else
- {
- movelist[i].val = HEVAL(s);
- hevalz++;
- s->value = movelist[i].val;
- s->depth = 1;
- tt_update(s, SHRT_MIN, SHRT_MAX);
- }
- }
- else
- {
- movelist[i].val = HEVAL(s);
- hevalz++;
- s->value = movelist[i].val;
- s->depth = 1;
- tt_store(s, SHRT_MIN, SHRT_MAX);
- }
- undomove(s, temp);
- }
- rawnodes += movecount;
- // node reordering here.
- if (s->turn == WHITE_PLAYER)
- qsort(movelist, movecount, sizeof(move), (void*)mincompare);
- else
- qsort(movelist, movecount, sizeof(move), (void*)maxcompare);
- // this is the end of the line, return best move.
- if (depth+1 >= tdepth)
- return movelist[0];
- done = 0;
- for (i=0; i < movecount && !done && i < options.engine.maxdepth; i++)
- {
- // already searched farther than we will in the TT, just return it.
- if (movelist[i].depth > tdepth - depth)
- return movelist[i];
- temp = savemove(s, movelist[i]);
- makemove(s, movelist[i]);
- stemp = search(s, depth+1, alpha, beta, tdepth, think);
- if (ok)
- {
- // this should perhaps check if tt_lookup still works
- // not life changing
- if (tdepth-depth > movelist[i].depth)
- {
- s->value = stemp.val;
- s->depth = tdepth-depth;
- tt_update(s, alpha, beta);
- }
- movelist[i].val = stemp.val;
- undomove(s,temp); // undo move.
- }
- else // times up, return back up the tree as fast as possible.
- {
- undomove(s,temp); // undo move.
- return movelist[i];
- }
- nodes++;
- // alpha-beta stuff:
- if (s->turn == WHITE_PLAYER)
- {
- if (movelist[i].val > alpha)
- {
- alpha = movelist[i].val;
- index = i;
- }
- }
- else
- {
- if (movelist[i].val < beta)
- {
- beta = movelist[i].val;
- index = i;
- }
- }
- if (alpha >= beta)
- {
- done = 1;
- }
- }
- /* XXX
- printf("movelist index = %d\n", index);
- if (movecount > 3)
- {
- randomizer = rand() %3;
- printf("randomizer = %d\n", randomizer);
- }
- */
- return movelist[index];
- }
- // print out a longlong in binary
- int pvec(ull v)
- {
- int i;
- printf("->");
- for (i=49; i >= 0; i--)
- {
- printf("%d", (int)((v >> i) & (ull)1));
- if (i%10 == 0)
- printf(" ");
- }
- printf("<-\n");
- return 0;
- }
- // bring out a nice representation of the playing board
- int pboard(state s)
- {
- int board[12][12];
- int i,j;
- int row, col;
- // make the whole board blanks
- for (i=0; i < 12; i++)
- for (j=0; j < 12; j++)
- board[i][j] = '.';
- // place player1 queens
- for (i=0; i < WHITEQUEENS; i++)
- {
- col = s.white_q_x[i];
- row = s.white_q_y[i];
- if (options.white_player == HUMAN) board[col][row] = i+48;
- else board[col][row] = 'W';
- }
- // place player2 queens
- for (i=0; i < BLACKQUEENS; i++)
- {
- col = s.black_q_x[i];
- row = s.black_q_y[i];
- if (options.black_player == HUMAN) board[col][row] = i+48;
- else board[col][row] = 'B';
- }
- // put walls on the board
- //pvec(s.blocks_bd[1]);
- for (i=0; i < 50; i++)
- {
- if ((s.blocks_bd[1] >> i) & 1)
- {
- board[i%10][i/10+5] = 'x';
- }
- }
- //pvec(s.blocks_bd[0]);
- for (i=0; i < 50; i++)
- {
- if ((s.blocks_bd[0] >> i) & 1)
- {
- board[i%10][i/10] = 'x';
- }
- }
- printf("\n");
- // print out the board
- for (i=9; i >= 0; i--)
- {
- printf("%2d ", i);
- for (j=0; j < 10; j++)
- {
- printf(" %c", board[j][i]);
- }
- printf("\n");
- }
- printf(" a b c d e f g h i j\n");
- //printf(" 0 1 2 3 4 5 6 7 8 9\n");
- printf("\n");
- return 0;
- }
- /*==============================================================================
- * getmove
- *
- * Gets the move coordinates from stdin. Does lots of nice error checking on the
- * input, and makes sure the move was legal. If no moves are available, the human
- * must have lost, so the game ends.
- */
- move getmove(state *s, int player)
- {
- char tok;
- int done = FALSE;
- move movelist[3000];
- int move_count;
- move m;
- char move_str[10];
- int i;
- move_count = children(s, movelist);
- if (move_count == 0)
- {
- printf("Ha ha ha, you lose SUCKER!\n");
- s->winner = s->turn^3;
- #ifndef GAMAZONS
- exit(0);
- #endif
- }
- do
- {
- i = 0;
- printf("player %d's move.\n", player);
- printf("queen newcol newrow burncol burnrow (ex. \"0 c4 c1\")\n");
- printf("Move> ");
- fflush(stdout);
- ok = 1;
- isearch(s, THINK);
- tok = get_token();
- if (isdigit(tok))
- {
- m.queen = tok - '0';
- move_str[i++] = tok;
- move_str[i++] = ' ';
- }
- else
- {
- printf("%c is not a valid queen\n\n", tok);
- clear_buf();
- continue;
- }
- tok = get_token();
- if (isdigit(tok - '1')) //convert from alpha char to alpha num
- {
- m.tocol = tok - 'a';
- move_str[i++] = tok;
- }
- else
- {
- printf("%c is not a valid column\n\n", tok);
- clear_buf();
- continue;
- }
- tok = get_token();
- if (isdigit(tok))
- {
- m.torow = tok - '0';
- move_str[i++] = tok;
- move_str[i++] = ' ';
- }
- else
- {
- printf("%c is not a valid row\n\n", tok);
- clear_buf();
- continue;
- }
- tok = get_token();
- if (isdigit(tok - '1')) //convert from alpha char to alpha num
- {
- m.wallcol = tok - 'a';
- move_str[i++] = tok;
- }
- else
- {
- printf("%c is not a valid column\n\n", tok);
- clear_buf();
- continue;
- }
- tok = get_token();
- if (isdigit(tok))
- {
- m.wallrow = tok - '0';
- move_str[i++] = tok;
- }
- else
- {
- printf("%c is not a valid row\n\n", tok);
- clear_buf();
- continue;
- }
- move_str[i] = '\0';
- //make sure it's a valid move
- if (!move_lookup(&m, movelist, move_count))
- {
- printf("%s is not a legal move\n", move_str);
- continue;
- }
- //User input verified
- done = TRUE;
- }
- while (done == FALSE);
- return m;
- }
- /*==============================================================================
- * get_token
- *
- * Retreives a token from stdin, ignores beginning whitespace.
- */
- char get_token()
- {
- char tok;
- tok = getc(movin);
- while (isspace(tok))
- tok = getc(movin);
- return tok;
- }
- /*==============================================================================
- * clear_buf
- *
- * Clears chars in the stdin buffer all the way up to and including the carriage
- * return.
- */
- void clear_buf()
- {
- while (getc(movin) != '\n');
- }
- /*==============================================================================
- * move_lookup
- *
- * Compares a given move with a move with the moves in the given movelist. If it's
- * found in the list, returns TRUE, otherwise returns FALSE.
- */
- int move_lookup(move *m, move movelist[], int move_count)
- {
- int i;
- for (i=0; i<move_count; i++)
- {
- if (m->queen != movelist[i].queen)
- continue;
- if (m->tocol != movelist[i].tocol)
- continue;
- if (m->torow != movelist[i].torow)
- continue;
- if (m->wallcol != movelist[i].wallcol)
- continue;
- if (m->wallrow != movelist[i].wallrow)
- continue;
- else
- {
- return TRUE;
- }
- }
- return FALSE;
- }
- // returns 1 if bit is set.
- int test(state *s, uchar col, uchar row)
- {
- //printf("sigh %d %d\n", col, row);
- if (row < 5)
- {
- if ( (s->blocks_bd[0] | s->white_bd[0] | s->black_bd[0] ) &
- (ull)1 << ((row*10) + col))
- return 1;
- return 0;
- }
- else // row > 5
- {
- if ( (s->blocks_bd[1] | s->white_bd[1] | s->black_bd[1]) &
- (ull)1 << ((((row-5)*10) + col)))
- {
- return 1;
- }
- return 0;
- }
- }
- // xor bit at col,row
- int xor(ull bd[2], uchar col, uchar row)
- {
- if (row < 5)
- {
- bd[0] ^= (ull)1 << ((row*10) + col);
- }
- else // row > 5
- {
- bd[1] ^= (ull)1 << ((((row-5)*10) + col));
- }
- return 1;
- }
- // takes a move that is to be made and returns a move that will
- // undo it.
- move savemove(state *s, move m)
- {
- move temp;
- temp.wallcol = m.wallcol;
- temp.wallrow = m.wallrow;
- temp.queen = m.queen;
- if (s->turn == WHITE_PLAYER)
- {
- temp.tocol = s->white_q_x[m.queen];
- temp.torow = s->white_q_y[m.queen];
- }
- else
- {
- temp.tocol = s->black_q_x[m.queen];
- temp.torow = s->black_q_y[m.queen];
- }
- return temp;
- }
- int undomove(state *s, move m)
- {
- s->turn ^= 3;
- if (s->turn == WHITE_PLAYER)
- {
- xor(s->white_bd, s->white_q_x[m.queen], s->white_q_y[m.queen]);
- s->white_q_x[m.queen] = m.tocol;
- s->white_q_y[m.queen] = m.torow;
- xor(s->white_bd, s->white_q_x[m.queen], s->white_q_y[m.queen]);
- }
- else
- {
- xor(s->black_bd, s->black_q_x[m.queen], s->black_q_y[m.queen]);
- s->black_q_x[m.queen] = m.tocol;
- s->black_q_y[m.queen] = m.torow;
- xor(s->black_bd, s->black_q_x[m.queen], s->black_q_y[m.queen]);
- }
- xor(s->blocks_bd, m.wallcol, m.wallrow);
- return 1;
- }
- // takes a move and does it.
- int makemove(state *s, move m)
- {
- if (s->turn == WHITE_PLAYER)
- {
- //printf("registering move w/ engine for white\n");
- xor(s->white_bd, s->white_q_x[m.queen], s->white_q_y[m.queen]);
- s->white_q_x[m.queen] = m.tocol;
- s->white_q_y[m.queen] = m.torow;
- xor(s->white_bd, s->white_q_x[m.queen], s->white_q_y[m.queen]);
- }
- else
- {
- //printf("registering move w/ engine for black\n");
- xor(s->black_bd, s->black_q_x[m.queen], s->black_q_y[m.queen]);
- s->black_q_x[m.queen] = m.tocol;
- s->black_q_y[m.queen] = m.torow;
- xor(s->black_bd, s->black_q_x[m.queen], s->black_q_y[m.queen]);
- }
- xor(s->blocks_bd, m.wallcol, m.wallrow);
- s->turn ^= 3;
- return 1;
- }
- // print out a move struct
- int pmove(move m)
- {
- printf("%d) %d -> %c%d ---> %c%d, val = %d\n", onmove,
- m.queen, m.tocol+97, m.torow, m.wallcol+97, m.wallrow, m.val);
- if (movin != stdin) // ?
- {
- fprintf(movout, "%d %c%d %c%d\n",
- m.queen, m.tocol+97, m.torow, m.wallcol+97, m.wallrow);
- fflush(movout);
- fseek(movout,0,0);
- //sleep(6);
- }
- return 0;
- }
- // set up the state
- int init(state *s)
- {
- int i;
- s->blocks_bd[0] = s->blocks_bd[1] = 0;
- s->white_bd[0] = s->white_bd[1] = 0;
- s->black_bd[0] = s->black_bd[1] = 0;
- s->turn = WHITE_PLAYER;
- for (i=0; i < 4; i++)
- {
- s->white_q_x[i] = 0;
- s->white_q_y[i] = 0;
- s->black_q_x[i] = 0;
- s->black_q_y[i] = 0;
- }
- // some lines to trip things up
- // xor(s->blocks_bd, 0,2);
- // xor(s->blocks_bd, 1,2);
- // xor(s->blocks_bd, 2,2);
- // xor(s->blocks_bd, 3,2);
- // xor(s->blocks_bd, 4,2);
- // xor(s->blocks_bd, 5,2);
- // xor(s->blocks_bd, 6,2);
- // xor(s->blocks_bd, 7,2);
- // xor(s->blocks_bd, 8,3);
- // xor(s->blocks_bd, 9,2);
- // place queen on the board
- xor(s->white_bd, 6, 0);
- s->white_q_x[0] = 6;
- s->white_q_y[0] = 0;
- xor(s->white_bd, 3, 0);
- s->white_q_x[1] = 3;
- s->white_q_y[1] = 0;
- xor(s->white_bd, 0, 3);
- s->white_q_x[2] = 0;
- s->white_q_y[2] = 3;
- xor(s->white_bd,9,3);
- s->white_q_x[3] = 9;
- s->white_q_y[3] = 3;
- xor(s->black_bd, 3, 9);
- s->black_q_x[0] = 3;
- s->black_q_y[0] = 9;
- xor(s->black_bd, 6, 9);
- s->black_q_x[1] = 6;
- s->black_q_y[1] = 9;
- xor(s->black_bd, 0, 6);
- s->black_q_x[2] = 0;
- s->black_q_y[2] = 6;
- xor(s->black_bd,9,6);
- s->black_q_x[3] = 9;
- s->black_q_y[3] = 6;
- return 0;
- }
- int meta_init()
- {
- if (!movin)
- {
- #ifdef DEBUG
- printf("not using fifos\n");
- #endif
- movin = stdin;
- movout = stdout;
- }
- pollstruct.fd = fileno(movin);
- pollstruct.events = POLLIN;
- pollstruct.revents = 0;
- return 1;
- }
- // test init function, used to set up potentially interesting
- // board states. Change call in main of init to x_init to put into
- // action.
- int x_init(state *s)
- {
- int i;
- s->blocks_bd[0] = s->blocks_bd[1] = 0;
- s->white_bd[0] = s->white_bd[1] = 0;
- s->black_bd[0] = s->black_bd[1] = 0;
- s->turn = WHITE_PLAYER;
- for (i=0; i < 4; i++)
- {
- s->white_q_x[i] = 0;
- s->white_q_y[i] = 0;
- s->black_q_x[i] = 0;
- s->black_q_y[i] = 0;
- }
- // place queen on the board
- xor(s->white_bd, 0, 0);
- s->white_q_x[0] = 0;
- s->white_q_y[0] = 0;
- xor(s->white_bd, 1, 0);
- s->white_q_x[1] = 1;
- s->white_q_y[1] = 0;
- xor(s->white_bd, 0, 1);
- s->white_q_x[2] = 0;
- s->white_q_y[2] = 1;
- xor(s->white_bd, 6, 0);
- s->white_q_x[3] = 6;
- s->white_q_y[3] = 0;
- xor(s->black_bd, 8, 0);
- s->black_q_x[0] = 8;
- s->black_q_y[0] = 0;
- xor(s->black_bd, 2, 0);
- s->black_q_x[1] = 2;
- s->black_q_y[1] = 0;
- xor(s->black_bd, 2, 1);
- s->black_q_x[2] = 2;
- s->black_q_y[2] = 1;
- xor(s->black_bd, 2, 2);
- s->black_q_x[3] = 2;
- s->black_q_y[3] = 2;
- /*
- xor(s->blocks_bd, 1,1);
- xor(s->blocks_bd, 1,2);
- xor(s->blocks_bd, 0,2);
- */
- xor(s->blocks_bd, 3,0);
- xor(s->blocks_bd, 3,1);
- xor(s->blocks_bd, 3,2);
- xor(s->blocks_bd, 3,3);
- xor(s->blocks_bd, 0,3);
- xor(s->blocks_bd, 1,3);
- xor(s->blocks_bd, 2,3);
- xor(s->blocks_bd, 4,3);
- xor(s->blocks_bd, 4,4);
- xor(s->blocks_bd, 5,4);
- xor(s->blocks_bd, 6,4);
- xor(s->blocks_bd, 7,4);
- xor(s->blocks_bd, 8,4);
- xor(s->blocks_bd, 9,4);
- /*
- xor(s->blocks_bd, 4,2);
- xor(s->blocks_bd, 5,2);
- xor(s->blocks_bd, 6,2);
- xor(s->blocks_bd, 7,2);
- xor(s->blocks_bd, 8,2);
- xor(s->blocks_bd, 9,2);
- */
- /*
- xor(s->blocks_bd, 4,0);
- xor(s->blocks_bd, 4,1);
- xor(s->blocks_bd, 5,0);
- xor(s->blocks_bd, 5,1);
- */
- /*
- xor(s->blocks_bd, 5,0);
- xor(s->blocks_bd, 5,1);
- xor(s->blocks_bd, 6,1);
- xor(s->blocks_bd, 7,0);
- xor(s->blocks_bd, 7,1);
- xor(s->blocks_bd, 8,1);
- xor(s->blocks_bd, 9,1);
- xor(s->blocks_bd, 9,0);
- */
- return 0;
- }
- #ifndef GAMAZONS
- /*==============================================================================
- * main
- *
- *
- */
- int main(int argc, char *argv[])
- {
- state *s;
- //struct move m;
- move temp;
- int i;
- // Initialize game states
- for (i=0; i<100; i++)
- states.s[i] = (state *) malloc(sizeof(state));
- states.current_state = 0;
- states.max_state = 0;
- s = states.s[0];
- parse_args(argc, argv);
- meta_init();
- init(s);
- printf("size of move = %d\n", sizeof(move));
- printf("size of state = %d\n", sizeof(state));
- pboard(*s);
- //test_fdiag(s);
- //test_bdiag(s);
- //test_gen_web_stream(s);
- //test_put_col(s);
- //test_put_row(s);
- //test_put_fdiag(s);
- //test_put_bdiag(s);
- #ifdef DEBUG_HEVAL
- xor(s->white_bd, 9, 3);
- xor(s->white_bd, 8, 2);
- s->white_q_x[3] = 8;
- s->white_q_y[3] = 2;
- xor(s->blocks_bd, 8, 3);
- s->turn = BLACK_PLAYER;
- pboard(*s);
- printf("board value is %d\n", HEVAL(s));
- pbvec(s->white_bd[0], s->white_bd[1]);
- #endif
- #ifndef DEBUG_HEVAL
- /* the main play loop. Gets a move, does a move, repeats.
- lobal ok is set to 1 for use with timeouts
- */
- for (;;)
- {
- dup_state(s, states.s[++(states.current_state)]);
- s = states.s[states.current_state];
- if (states.current_state > states.max_state)
- states.max_state = states.current_state;
- if (options.white_player == HUMAN)
- {
- temp = getmove(s, 1);
- makemove(s, temp);
- onmove++;
- pboard(*s);
- }
- else
- {
- ok = 1;
- start = time(NULL);
- temp = isearch(s, NOTHINK);
- printf("WHITE selected: ");
- pmove(temp);
- makemove(s,temp);
- onmove++;
- pboard(*s);
- }
- dup_state(s, states.s[++(states.current_state)]);
- s = states.s[states.current_state];
- if (states.current_state > states.max_state)
- states.max_state = states.current_state;
- if (options.black_player == HUMAN)
- {
- temp = getmove(s, 2);
- makemove(s, temp);
- onmove++;
- pboard(*s);
- }
- else
- {
- ok = 1;
- start = time(NULL);
- temp = isearch(s, NOTHINK);
- printf("BLACK selected: ");
- pmove(temp);
- makemove(s,temp);
- onmove++;
- pboard(*s);
- }
- }
- #endif
- return 0;
- }
- #endif //ifndef GAMAZONS
- #ifdef GAMAZONS
- /*==============================================================================
- * init_engine
- *
- *
- *
- */
- void init_engine()
- {
- state *s;
- //struct move m;
- move temp;
- int i;
- char *home_env;
- srand(time(NULL));
- // Initialize game states
- for (i=0; i<100; i++)
- states.s[i] = (state *) malloc(sizeof(state));
- states.current_state = 0;
- states.max_state = 0;
- s = states.s[0];
- s->turn = WHITE_PLAYER;
- s->winner = 0;
- state_hash = create_hash(s);
- meta_init();
- init(s);
- dup_state(s, states.s[++(states.current_state)]);
- /* set default options */
- options.engine.maxdepth=20;
- options.engine.maxwidth=3000;
- options.engine.timeout=1;
- options.white_player=HUMAN;
- options.black_player=HUMAN;
- options.print_statistics=FALSE;
- home_env = getenv("HOME");
- strcpy(options.hist_dir, home_env);
- strcat(options.hist_dir, "/");
- if (!load_images_from_theme(PACKAGE_DATA_DIR "/gamazons/default.theme"))
- {
- fprintf(stderr, "Cannot find theme file %s\n", PACKAGE_DATA_DIR "/gamazons/default.theme");
- exit(1);
- }
- #ifdef DEBUG
- printf("white piece image = %s\n", options.images.white_piece);
- #endif
- load_values_from_file();
- }
- /*==============================================================================
- * load_values_from_file
- *
- * If a .gamazons file is found in the user's home directory, it will attempt to
- * load the values stored therein. Any variables it doesn't recognize will be
- * silently ignored.
- */
- void load_values_from_file()
- {
- char *home, file[256];
- FILE *rc_fd;
- char variable[256];
- char buffer[256];
- int value;
- char ch;
- if (!(home = getenv("HOME")))
- return;
- strcpy(file, home);
- strcat(file, "/.gamazons");
- #ifdef DEBUG
- printf("looking for the file %s\n", file);
- #endif
- rc_fd = fopen(file, "r");
- if(rc_fd == NULL)
- return;
- while (fscanf(rc_fd, "%s", variable) != EOF)
- {
- while (ch = fgetc(rc_fd))
- {
- if (ch == EOF)
- return;
- if (ch == '=')
- break;
- }
- if (strcmp(variable, "WHITE_PLAYER") == 0)
- {
- fscanf(rc_fd, "%d", &value);
- options.white_player = value;
- }
- else if (strcmp(variable, "BLACK_PLAYER") == 0)
- {
- fscanf(rc_fd, "%d", &value);
- options.black_player = value;
- }
- else if (strcmp(variable, "TIMEOUT") == 0)
- {
- fscanf(rc_fd, "%d", &value);
- if (value > 0)
- options.engine.timeout = value;
- else
- options.engine.timeout = 1;
- }
- else if (strcmp(variable, "MAXWIDTH") == 0)
- {
- fscanf(rc_fd, "%d", &value);
- if (value > 0)
- options.engine.maxwidth = value;
- else
- options.engine.maxwidth = 1;
- }
- else if (strcmp(variable, "MAXDEPTH") == 0)
- {
- fscanf(rc_fd, "%d", &value);
- if (value > 0)
- options.engine.maxdepth = value;
- else
- options.engine.maxdepth = 1;
- }
- else if (strcmp(variable, "REPLAY_DELAY") == 0)
- {
- fscanf(rc_fd, "%d", &value);
- if (value > 0)
- options.replay_delay = value;
- else
- options.replay_delay = 1;
- }
- else if (strcmp(variable, "MOVEMENT_SPEED") == 0)
- {
- fscanf(rc_fd, "%d", &value);
- if (value > 0 && value <= 10)
- options.movement_speed = value;
- else
- options.movement_speed = 1;
- }
- else if (strcmp(variable, "WHITE_PIECE") == 0)
- {
- fscanf(rc_fd, "%s", buffer);
- strcpy(options.images.white_piece, buffer);
- }
- else if (strcmp(variable, "BLACK_PIECE") == 0)
- {
- fscanf(rc_fd, "%s", buffer);
- strcpy(options.images.black_piece, buffer);
- }
- else if (strcmp(variable, "WHITE_SQUARE") == 0)
- {
- fscanf(rc_fd, "%s", buffer);
- strcpy(options.images.white_sq, buffer);
- }
- else if (strcmp(variable, "GREY_SQUARE") == 0)
- {
- fscanf(rc_fd, "%s", buffer);
- strcpy(options.images.grey_sq, buffer);
- }
- else if (strcmp(variable, "ARROW_SQUARE") == 0)
- {
- fscanf(rc_fd, "%s", buffer);
- strcpy(options.images.arrow_sq, buffer);
- }
- else if (strcmp(variable, "HIST_DIR") == 0)
- {
- fscanf(rc_fd, "%s", buffer);
- strcpy(options.hist_dir, buffer);
- }
- else if (strcmp(variable, "DRAW_GRID") == 0)
- {
- fscanf(rc_fd, "%s", buffer);
- if (strcmp(buffer, "TRUE") == 0)
- options.images.grid = TRUE;
- else
- options.images.grid = FALSE;
- }
- }
- fclose(rc_fd);
- }
- /*==============================================================================
- * store_values_in_file
- *
- * Creates/overwrites a .gamazons file in the user's home directory. Stores
- * the values in the options struct in it.
- */
- void store_values_in_file()
- {
- char *home, file[256];
- FILE *rc_fd;
- #ifdef GAMAZONS
- GtkWidget *delay = (GtkWidget *)lookup_widget(main_window, "ReplayDelaySpinner");
- GtkWidget *speed = (GtkWidget *)lookup_widget(main_window, "MovementSpeedSpinner");
- #endif
- if (!(home = getenv("HOME")))
- return;
- strcpy(file, home);
- strcat(file, "/.gamazons");
- #ifdef DEBUG
- printf("looking for the file %s\n", file);
- #endif
- rc_fd = fopen(file, "w");
- if (rc_fd == NULL)
- return;
-
- fprintf(rc_fd, "WHITE_PLAYER = ");
- fprintf(rc_fd, "%d\n", options.white_player);
- fprintf(rc_fd, "BLACK_PLAYER = ");
- fprintf(rc_fd, "%d\n", options.black_player);
- fprintf(rc_fd, "TIMEOUT = ");
- fprintf(rc_fd, "%d\n", options.engine.timeout);
- fprintf(rc_fd, "MAXWIDTH = ");
- fprintf(rc_fd, "%d\n", options.engine.maxwidth);
- fprintf(rc_fd, "MAXDEPTH = ");
- fprintf(rc_fd, "%d\n", options.engine.maxdepth);
- fprintf(rc_fd, "WHITE_PIECE = ");
- fprintf(rc_fd, "%s\n", options.images.white_piece);
- fprintf(rc_fd, "BLACK_PIECE = ");
- fprintf(rc_fd, "%s\n", options.images.black_piece);
- fprintf(rc_fd, "WHITE_SQUARE = ");
- fprintf(rc_fd, "%s\n", options.images.white_sq);
- fprintf(rc_fd, "GREY_SQUARE = ");
- fprintf(rc_fd, "%s\n", options.images.grey_sq);
- fprintf(rc_fd, "ARROW_SQUARE = ");
- fprintf(rc_fd, "%s\n", options.images.arrow_sq);
- fprintf(rc_fd, "HIST_DIR = ");
- fprintf(rc_fd, "%s\n", options.hist_dir);
- fprintf(rc_fd, "DRAW_GRID = ");
- if (options.images.grid == TRUE)
- fprintf(rc_fd, "%s\n", "TRUE");
- else
- fprintf(rc_fd, "%s\n", "FALSE");
- #ifdef GAMAZONS
- fprintf(rc_fd, "REPLAY_DELAY = ");
- options.replay_delay = gtk_spin_button_get_value_as_int((GtkSpinButton *)delay);
- fprintf(rc_fd, "%d\n", options.replay_delay);
- fprintf(rc_fd, "MOVEMENT_SPEED = ");
- options.movement_speed = gtk_spin_button_get_value_as_int((GtkSpinButton *)speed);
- fprintf(rc_fd, "%d\n", options.movement_speed);
- #endif
- fclose(rc_fd);
- }
- /*==============================================================================
- * load_images_from_theme
- *
- * This file will read image paths from a theme file. These values get loaded
- * into the options struct, and subsequently used to draw the board.
- */
- int load_images_from_theme(char *theme)
- {
- char *home, file[256];
- FILE *theme_fd;
- char variable[256];
- char buffer[256];
- int value;
- char ch;
- theme_fd = fopen(theme, "r");
- if(theme_fd == NULL)
- {
- fprintf(stderr, "Can't open theme file %s\n", theme);
- return FALSE;
- }
- while (fscanf(theme_fd, "%s", variable) != EOF)
- {
- while (ch = fgetc(theme_fd))
- {
- if (ch == EOF)
- return TRUE;
- if (ch == '=')
- break;
- }
- if (strcmp(variable, "WHITE_PIECE") == 0)
- {
- fscanf(theme_fd, "%s", buffer);
- strcpy(options.images.white_piece, PACKAGE_DATA_DIR "/pixmaps/gamazons/");
- strcat(options.images.white_piece, buffer);
- }
- else if (strcmp(variable, "BLACK_PIECE") == 0)
- {
- fscanf(theme_fd, "%s", buffer);
- strcpy(options.images.black_piece, PACKAGE_DATA_DIR "/pixmaps/gamazons/");
- strcat(options.images.black_piece, buffer);
- }
- else if (strcmp(variable, "WHITE_SQUARE") == 0)
- {
- fscanf(theme_fd, "%s", buffer);
- strcpy(options.images.white_sq, PACKAGE_DATA_DIR "/pixmaps/gamazons/");
- strcat(options.images.white_sq, buffer);
- }
- else if (strcmp(variable, "GREY_SQUARE") == 0)
- {
- fscanf(theme_fd, "%s", buffer);
- strcpy(options.images.grey_sq, PACKAGE_DATA_DIR "/pixmaps/gamazons/");
- strcat(options.images.grey_sq, buffer);
- }
- else if (strcmp(variable, "ARROW_SQUARE") == 0)
- {
- fscanf(theme_fd, "%s", buffer);
- strcpy(options.images.arrow_sq, PACKAGE_DATA_DIR "/pixmaps/gamazons/");
- strcat(options.images.arrow_sq, buffer);
- }
- else if (strcmp(variable, "DRAW_GRID") == 0)
- {
- fscanf(theme_fd, "%s", buffer);
- if (strcmp(buffer, "TRUE") == 0)
- options.images.grid = TRUE;
- else
- options.images.grid = FALSE;
- }
- }
- fclose(theme_fd);
- return TRUE;
- }
- #endif
- /*==============================================================================
- * print_usage_menu
- *
- * Displays a list of all command line options
- */
- void print_usage_menu()
- {
- printf("Amazons Usage:\n");
- printf("amazons [OPTIONS]\n");
- printf(" -d #: Sets the maximum search depth\n");
- printf(" -h: Prints this help menu\n");
- printf(" -p #: User plays against the computer (1 white, 2 black)\n");
- printf(" -s: Prints out interesting statistics\n");
- printf(" -t #: Sets the time limit between moves\n");
- printf("\n\n");
- }
- /* parse args
- *
- * Handles the arguments passed into the program.
- *
- * Note: this expects all arguments to be listed separately,
- * each with it's own '-'
- */
- void parse_args(int argc, char *argv[])
- {
- int i = 1;
- //Set defaults
- options.engine.maxdepth=20;
- options.engine.maxwidth=5000;
- options.engine.timeout=2;
- options.white_player=HUMAN;
- options.black_player=AI;
- options.print_statistics=FALSE;
- while (i < argc)
- {
- switch(argv[i][1])
- {
- case 'd':
- options.engine.maxdepth = atoi(argv[++i]);
- i++;
- break;
- case 'h':
- print_usage_menu();
- exit(0);
- case 'p':
- if (atoi(argv[++i]) == 1)
- options.white_player = HUMAN;
- else
- options.black_player = HUMAN;
- i++;
- break;
- case 'f':
- #ifdef DEBUG
- printf("opening movin\n");
- #endif
- movin = fopen(argv[++i], "r+");
- #ifdef DEBUG
- printf("success\n");
- printf("opening movout\n");
- #endif
- movout = fopen(argv[++i], "r+");
- #ifdef DEBUG
- printf("success\n");
- #endif
- //fprintf(fifop, "wubba wubba\n");
- //fflush(fifop);
- //printf("open success\n");
- i++;
- break;
- case 's':
- options.print_statistics = TRUE;
- i++;
- break;
- case 't':
- options.engine.timeout = atoi(argv[++i]);
- i++;
- break;
- case 'w':
- options.engine.maxdepth = atoi(argv[++i]);
- i++;
- break;
- default:
- printf("Unknown argument %s\n", argv[i]);
- print_usage_menu();
- exit(1);
- }
- }
- }
- void print_stats()
- {
- printf("TT Stats:\n");
- printf(" # nodes over written: %d\n", tt_overwrite);
- printf(" # of nodes stored: %d\n", tt_stores);
- printf(" # of updates made: %d\n", tt_updates);
- printf(" # of lookups made: %d\n", tt_lookups);
- printf(" # of lookups found: %d\n", tt_lookup_finds);
- printf("\n");
- printf("Heuristic Stats:\n");
- printf(" # of heuristic calls %d\n", heval_calls);
- }
- void dup_state(state *s_old, state *s_new)
- {
- int i;
- s_new->white_bd[0] = s_old->white_bd[0];
- s_new->white_bd[1] = s_old->white_bd[1];
- s_new->blocks_bd[0] = s_old->blocks_bd[0];
- s_new->blocks_bd[1] = s_old->blocks_bd[1];
- s_new->black_bd[0] = s_old->black_bd[0];
- s_new->black_bd[1] = s_old->black_bd[1];
- for (i=0; i<4; i++)
- {
- s_new->white_q_x[i] = s_old->white_q_x[i];
- s_new->black_q_x[i] = s_old->black_q_x[i];
- s_new->white_q_y[i] = s_old->white_q_y[i];
- s_new->black_q_y[i] = s_old->black_q_y[i];
- }
- s_new->turn = s_old->turn;
- #ifdef DEBUG
- printf("old turn is %d, new turn is %d\n", s_old->turn, s_new->turn);
- #endif
- s_new->value = s_old->value;
- s_new->depth = s_old->depth;
- s_new->winner = s_old->winner;
- }