Example #1
0
float minimax( const dtype board[16][16], const dtype available[2][21], const int score[2], const int player, 
				const int depth, float alpha, float beta ){
	
	if(depth == 0){
		float utility = evalfunc ( board, available, score, player_max);
		return utility;
	}

	move moves[2000];
	int movesFound, i,j;
	movesFound = getMoveList( moves, board, available, player, score );

	if(movesFound == 0){
	
		dtype n_board[16][16]; dtype n_available[2][21]; int n_score[2]; int n_player;

		// Copy board data to output
		for( i = 0; i < 16; i++ )
			for( j = 0; j < 16; j++ )
				n_board[i][j] = board[i][j];
		
		// Copy piece data to output
		for( i = 0; i < 2; i++ )
			for( j = 0; j < 21; j++ )
				n_available[i][j] = available[i][j];
			
		// Copy piece data to output array
		for( i = 0; i < 2; i++ ) n_score[i] = score[i];

		n_player = 3-player;
		
		float newUtility = minimax( n_board, n_available, n_score, n_player, depth-1, alpha, beta );
		
		if( player == player_max ) { 
			if( newUtility > alpha ) {
				alpha = newUtility; 
			}
		}
		else if( newUtility < beta ) { 
			beta = newUtility;
		}
		
		return (player==player_max) ? alpha : beta;		
		
	}

	for( i = 0; i < movesFound; i++ ){

		dtype n_board[16][16]; dtype n_available[2][21]; int n_score[2]; int n_player;
		
		simulateMove( moves[i], board, available, score, player, 
						n_board, n_available, n_score, &n_player );

		float newUtility = minimax( n_board, n_available, n_score, n_player, depth-1, alpha, beta );
		
		if( player == player_max ) { 
			if( newUtility > alpha ) {
				alpha = newUtility; 
			}
		}
		else if( newUtility < beta ) { 
			beta = newUtility;
		}

		//prune
		if( beta <= alpha ) break;		
	}
	return (player==player_max) ? alpha : beta;	
}
Example #2
0
LISP eval (LISP expr, LISP *ctxp)
{
	LISP ctx = ctxp ? *ctxp : NIL;
	LISP func;
again:
	if (expr == NIL)
		return (NIL);

	/* Если это символ, берем его значение */
	if (istype (expr, TSYMBOL)) {
		/* Поиск значения по контексту */
		LISP pair = findatom (expr, ctx);
		if (pair == NIL) {
			fprintf (stderr, "unbound symbol: `%s'\n", symname (expr));
			return (NIL);
		}
		return (cdr (pair));
	}

	/* Все, что не атом и не список, не вычисляется */
	if (! istype (expr, TPAIR))
		return (expr);

	/* Перебираем специальные формы.
	 * quote define set! begin lambda let let* letrec if
	 * and or cond else => quasiquote unquote unquote-splicing
	 */
	/* Зарезервированные имена:
	 * delay do case
	 */
	func = car (expr);
	if (istype (func, TSYMBOL)) {
		char *funcname = symname (func);
		if (!strcmp (funcname, "quote")) {
			if (! istype (expr = cdr (expr), TPAIR))
				return (NIL);
			return (car (expr));
		}
		if (!strcmp (funcname, "define")) {
			LISP value, atom, pair, arg;
			int lambda;
			if (! istype (expr = cdr (expr), TPAIR))
				return (NIL);
			lambda = istype (atom = car (expr), TPAIR);
			if (lambda) {
				/* define, совмещенный с lambda */
				arg = cdr (atom);
				atom = car (atom);
			}
			if (! istype (atom, TSYMBOL) ||
			    ! istype (expr = cdr (expr), TPAIR))
				return (NIL);
			pair = findatom (atom, ctx);
			if (pair == NIL) {
				/* Расширяем контекст */
				pair = cons (atom, NIL);
				if (ctxp)
					/* локальный контекст */
					*ctxp = ctx = cons (pair, ctx);
				else
					/* контекст верхнего уровня */
					ENV = cons (pair, ENV);
			}
			if (lambda)
				value = closure (cons (arg, expr), ctx);
			else
				value = evalblock (expr, ctx);
			setcdr (pair, value);
			return (value);
		}
		if (!strcmp (funcname, "set!")) {
			LISP value = NIL;
			if (! istype (expr = cdr (expr), TPAIR))
				return (NIL);
			if (istype (cdr (expr), TPAIR))
				value = evalblock (cdr (expr), ctx);
			setatom (car (expr), value, ctx);
			return (value);
		}
		if (!strcmp (funcname, "begin"))
			return (evalblock (cdr (expr), ctx));
		if (!strcmp (funcname, "lambda")) {
			LISP arg = NIL;
			if (istype (expr = cdr (expr), TPAIR)) {
				arg = car (expr);
				if (! istype (expr = cdr (expr), TPAIR))
					expr = NIL;
			}
			return (closure (cons (arg, expr), ctx));
		}
		if (!strcmp (funcname, "let")) {
			LISP arg = NIL, oldctx = ctx;
			if (istype (expr = cdr (expr), TPAIR)) {
				arg = car (expr);
				if (! istype (expr = cdr (expr), TPAIR))
					expr = NIL;
			}
			/* Расширяем контекст новыми переменными */
			while (istype (arg, TPAIR)) {
				LISP var = car (arg);
				arg = cdr (arg);
				/* Значения вычисляем в старом контексте */
				if (istype (var, TPAIR))
					ctx = cons (cons (car (var),
						evalblock (cdr (var), oldctx)),
						ctx);
				else if (istype (var, TSYMBOL))
					ctx = cons (cons (var, NIL), ctx);
			}
			return (evalblock (expr, ctx));
		}
		if (!strcmp (funcname, "let*")) {
			LISP arg = NIL;
			if (istype (expr = cdr (expr), TPAIR)) {
				arg = car (expr);
				if (! istype (expr = cdr (expr), TPAIR))
					expr = NIL;
			}
			/* Расширяем контекст новыми переменными */
			while (istype (arg, TPAIR)) {
				LISP var = car (arg);
				arg = cdr (arg);
				/* Значения вычисляем в текущем контексте */
				if (istype (var, TPAIR))
					ctx = cons (cons (car (var),
						evalblock (cdr (var), ctx)),
						ctx);
				else if (istype (var, TSYMBOL))
					ctx = cons (cons (var, NIL), ctx);
			}
			return (evalblock (expr, ctx));
		}
		if (!strcmp (funcname, "letrec")) {
			LISP arg = NIL, a;
			if (istype (expr = cdr (expr), TPAIR)) {
				arg = car (expr);
				if (! istype (expr = cdr (expr), TPAIR))
					expr = NIL;
			}
			/* Расширяем контекст новыми переменными с пустыми значениями */
			for (a=arg; istype (a, TPAIR); a=cdr(a)) {
				LISP var = car (a);
				if (istype (var, TPAIR))
					ctx = cons (cons (car (var), NIL), ctx);
				else if (istype (var, TSYMBOL))
					ctx = cons (cons (var, NIL), ctx);
			}
			/* Вычисляем значения в новом контексте */
			for (a=arg; istype (a, TPAIR); a=cdr(a)) {
				LISP var = car (a);
				if (istype (var, TPAIR))
					setatom (car (var),
						evalblock (cdr (var), ctx),
						ctx);
			}
			return (evalblock (expr, ctx));
		}
		if (!strcmp (funcname, "if")) {
			LISP iftrue = NIL, iffalse = NIL, test;
			if (! istype (expr = cdr (expr), TPAIR))
				return (NIL);
			test = car (expr);
			if (istype (expr = cdr (expr), TPAIR)) {
				iftrue = car (expr);
				iffalse = cdr (expr);
			}
			if (eval (test, &ctx) != NIL)
				return (eval (iftrue, &ctx));
			return (evalblock (iffalse, ctx));
		}
		if (!strcmp (funcname, "and")) {
			while (istype (expr = cdr (expr), TPAIR))
				if (eval (car (expr), &ctx) == NIL)
					return (NIL);
			return (T);
		}
		if (!strcmp (funcname, "or")) {
			while (istype (expr = cdr (expr), TPAIR))
				if (eval (car (expr), &ctx) == NIL)
					return (T);
			return (NIL);
		}
		if (!strcmp (funcname, "cond")) {
			LISP oldctx = ctx, test, clause;
			while (istype (expr = cdr (expr), TPAIR)) {
				if (! istype (clause = car (expr), TPAIR))
					continue;
				ctx = oldctx;
				if (istype (car (clause), TSYMBOL) &&
				    ! strcmp (symname (car (clause)), "else"))
					return (evalblock (cdr (clause), ctx));
				test = eval (car (clause), &ctx);
				if (test == NIL ||
				    ! istype (clause = cdr (clause), TPAIR))
					continue;
				if (istype (car (clause), TSYMBOL) &&
				    ! strcmp (symname (car (clause)), "=>")) {
					clause = evalblock (cdr (clause), ctx);
					if (istype (clause, THARDW))
						return ((*hardwval (clause)) (cons (test, NIL), ctx));
					if (istype (clause, TCLOSURE))
						return (evalclosure (clause, cons (test, NIL)));
					return (NIL);
				}
				return (evalblock (clause, ctx));
			}
			return (NIL);
		}
		if (!strcmp (funcname, "quasiquote")) {
			if (! istype (expr = cdr (expr), TPAIR))
				return (NIL);
			return (quasiquote (car (expr), ctx, 0));
		}
		if (!strcmp (funcname, "unquote") ||
		    !strcmp (funcname, "unquote-splicing")) {
			if (! istype (expr = cdr (expr), TPAIR))
				return (NIL);
			expr = car (expr);
			goto again;
		}
	}

	/* Вычисляем все аргументы */
	expr = evallist (expr, ctx);
	return (evalfunc (car (expr), cdr (expr), ctxp ? *ctxp : TOPLEVEL));
}