home *** CD-ROM | disk | FTP | other *** search
- /* ab.c
- *
- * Crude, simple alpha-beta search.
- *
- * No pruning, yet.
- *
- * Requires the following to be defined:
- * ab_position_t: Type that defines a board position.
- * ab_score_t: Score type for score of a move.
- * AB_WIN_SCORE: Score that signifies a win.
- * AB_MAX_MOVES: Max moves that will ever be available from a single
- * position.
- * ab_move_t: Type that definies a move.
- * ab_storage_t: Data needed to store a move's effects and undo them.
- * ab_score_t AB_MOVE_VAL(move): Value of a move.
- * int AB_PLAYER_TO_MOVE(pos): 0 or 1.
- * int ab_generate_moves(pos, moves);
- * ab_score_t ab_do_move(position, move, storage): Make move to position.
- * void ab_undo_move(position, storage): Undo a move.
- * int ab_move_cmp(mv1, mv2): Return >0 if mv1 has a higher score,
- * is better, <0 if mv2 is better. Should never return 0.
- */
-
-
- #include "mancala.h"
- #include <stdio.h>
-
-
- static ab_score_t rsearch(ab_position_t *pos, int depth,
- ab_move_t *bestmove);
-
-
- ab_move_t ab_search(ab_position_t *pos, int depth) {
- ab_move_t result;
- ab_score_t score;
-
- do {
- score = rsearch(pos, depth, &result);
- --depth;
- } while ((score <= -AB_WIN_SCORE) && (depth > 0));
- return(result);
- }
-
-
- static ab_score_t rsearch(ab_position_t *pos, int depth,
- ab_move_t *bestmove) {
- ab_move_t moves[AB_MAX_MOVES];
- int n_moves, i, tomove = AB_PLAYER_TO_MOVE(*pos);
- ab_storage_t mvmade;
- ab_score_t bscore, cscore, mscore;
-
- bscore = -AB_WIN_SCORE;
- n_moves = ab_generate_moves(pos, moves);
- if (n_moves == 0)
- return(0);
- qsort(moves, n_moves, sizeof(ab_move_t), ab_move_cmp);
- if (bestmove != NULL)
- *bestmove = moves[0];
- if (AB_MOVE_VAL(moves[0]) >= AB_WIN_SCORE)
- return(AB_WIN_SCORE);
- else if (AB_MOVE_VAL(moves[0]) <= -AB_WIN_SCORE)
- return(-AB_WIN_SCORE);
- if (depth == 1)
- return(AB_MOVE_VAL(moves[0]));
- for (i = 0; i < n_moves; ++i) {
- cscore = ab_do_move(pos, &moves[i], &mvmade);
- mscore = rsearch(pos, depth - 1, NULL);
- if (AB_PLAYER_TO_MOVE(*pos) != tomove)
- mscore = -mscore;
- ab_undo_move(pos, &mvmade);
- if (mscore >= AB_WIN_SCORE) {
- if (bestmove != NULL)
- *bestmove = moves[i];
- return(AB_WIN_SCORE);
- }
- if (mscore > -AB_WIN_SCORE) {
- cscore += mscore;
- if (cscore > bscore) {
- bscore = cscore;
- if (bestmove != NULL)
- *bestmove = moves[i];
- }
- }
- }
- return(bscore);
- }
-