コード例 #1
0
/** Removes the first edge e = (s,s') with s' in passed from the linked list associated to s in succ_to_visit if there is one, the first edge of the list otherwise
 	Returns that edge
 	Note that t belongs to P_O
 	Note that the successors list is supposed to be non empty (a test must be done before) */
static safety_game_edge*
get_first_successor_passed_non_losing(tuple *t, GHashTable *succ_to_visit, GHashTable *passed, antichain *losing_PO, antichain *losing_PI) {
	hash_table_key* key = new_hash_table_key(t, -1);

	// Try to retrieve the successors to visit list from succ_to_visit
	GList *succ_list = g_hash_table_lookup(succ_to_visit, key);
	safety_game_edge* first_succ_passed;
	GList *curlink = succ_list;
	char found = FALSE;
	int i=0;
	while(curlink != NULL) {
		if(is_passed(((safety_game_edge*)curlink->data)->to, passed) == TRUE && is_losing(((safety_game_edge*)curlink->data)->to, losing_PO, losing_PI) == FALSE) { // is passed?
			first_succ_passed = curlink->data;
			succ_list = g_list_delete_link(succ_list, curlink);
			g_hash_table_insert(succ_to_visit, (gconstpointer*)key, (gconstpointer*)succ_list);
			found = TRUE;
			break;
		}
		i++;
		curlink = curlink->next;
	}
	if(found == FALSE) { // no succ passed?
		first_succ_passed = succ_list->data;
		succ_list = remove_first(succ_list);
		g_hash_table_insert(succ_to_visit, (gconstpointer*)key, (gconstpointer*)succ_list);
	}

	return first_succ_passed;
}
コード例 #2
0
ファイル: search_full.cpp プロジェクト: raimarHD/lcec
static int full_new_depth(int depth, int move, board_t * board, bool single_reply, bool in_pv, int height, bool extended, bool * cap_extended, int ThreadId) {

   int new_depth;

   ASSERT(depth_is_ok(depth));
   ASSERT(move_is_ok(move));
   ASSERT(board!=NULL);
   ASSERT(single_reply==true||single_reply==false);
   ASSERT(in_pv==true||in_pv==false);

   ASSERT(depth>0);

   new_depth = depth - 1;
   *cap_extended = false;
   
   if (in_pv && board->square[MOVE_TO(move)] != Empty && !PIECE_IS_PAWN(board->square[MOVE_TO(move)])){
	   if ((board->piece_size[White] + board->piece_size[Black]) == 3){
			return new_depth+1;
	   }
	   else if ((board->piece_size[White] == 3 && board->piece_size[Black] == 2) 
		   || (board->piece_size[White] == 2 && board->piece_size[Black] == 3))
		   return new_depth+1; 
   }
   if ((single_reply && ExtendSingleReply)
		//|| (in_pv && MOVE_TO(move) == board->cap_sq // recapture
		//	&& see_move(move,board) >= -100 /*|| ABS(VALUE_PIECE(board->square[MOVE_TO(move)])-VALUE_PIECE(board->square[MOVE_FROM(move)])) <= 250 )*/)  
		//|| (in_pv && PIECE_IS_PAWN(MOVE_PIECE(move,board))
		//	  && (PAWN_RANK(MOVE_TO(move),board->turn) == Rank7 || PAWN_RANK(MOVE_TO(move),board->turn) == Rank6))
		//|| (in_pv &&  board->square[MOVE_TO(move)] != PieceNone256 && SearchCurrent[ThreadId]->act_iteration-height >= 6 && see_move(move,board) >= -100) 
		//|| (in_pv &&  board->square[MOVE_TO(move)] != PieceNone256 && !extended && see_move(move,board) >= -100)
		//|| (in_pv && mate_threat == true)
		|| move_is_check(move,board) && (in_pv || see_move(move,board) >= -100)) {
        // @tried no check extension in endgame (~ -5 elo)
        // @tried no bad SEE check extension in PV (~ -5 elo)
		return new_depth+1;
   }
   if (in_pv && PIECE_IS_PAWN(MOVE_PIECE(move,board))){
			if (is_passed(board,MOVE_TO(move)))
				return new_depth+1;
   }

  if (in_pv &&  board->square[MOVE_TO(move)] != PieceNone256 
	   && !extended && see_move(move,board) >= -100){
		   *cap_extended = true;
		   return new_depth+1;
   }
  
   ASSERT(new_depth>=0&&new_depth<=depth);

   return new_depth;
}
コード例 #3
0
ファイル: search_full.cpp プロジェクト: raimarHD/lcec
static bool move_is_dangerous(int move, const board_t * board) {

   int piece;

   ASSERT(move_is_ok(move));
   ASSERT(board!=NULL);

   ASSERT(!move_is_tactical(move,board));

   piece = MOVE_PIECE(move,board);

   if (PIECE_IS_PAWN(piece)
    && is_passed(board,MOVE_TO(move)) /*PAWN_RANK(MOVE_TO(move),board->turn) >= Rank7*/) {
      return true;
   }

   return false;
}
コード例 #4
0
/** Part of the winning positions computation: adds t to the antichain of winning positions
 	If t belongs to P_O, find a successor non losing passed and add update the winning positions with it
 	If t belongs to P_I, computes all successors and update the winning positions with each of them
 	Optimization (maximum successors for P_I): if t belongs to P_I, only deal the maximum successors of t **/
static void
update_winning_positions(tuple *t, alphabet_info *alphabet, safety_game *winning_positions, GHashTable *mapping_table, antichain* losing_PO, antichain* losing_PI, GHashTable* passed) {
	hash_table_key* key = new_hash_table_key(t, -1);

	// Insert t in the mapping_table
	char *value = (char*)malloc(sizeof(char));
	value[0] = TRUE;
	g_hash_table_insert(mapping_table, (gconstpointer*)key, (gconstpointer*)value);

	int nb_outgoing_edges, sigma_size;
	antichain *max_succ;
	if(t->cf->player == P_O) {
		nb_outgoing_edges = 1;
		sigma_size = alphabet->sigma_output_size;
		add_element_to_antichain(winning_positions->positions_O, t, (void*)compare_tuples);
	}
	else {
		nb_outgoing_edges = alphabet->sigma_input_size;
		sigma_size = alphabet->sigma_input_size;
		add_element_to_antichain(winning_positions->positions_I, t, (void*)compare_tuples);
		max_succ = maximal_tuple_succ(t, alphabet);
	}

	// Compute successors of t
	tuple *cur_succ, *good_succ;
	int i;
	char *cur_value;
	hash_table_key *cur_key;
	char found = FALSE;
	for(i=0; i<sigma_size; i++) {
		cur_succ = tuple_succ(t, i, alphabet);

		if(t->cf->player == P_O) { //t belongs to P_O
			if((is_losing(cur_succ, losing_PO, losing_PI) == FALSE) && (is_passed(cur_succ, passed) == TRUE)) { // Not losing and passed?
				cur_key = new_hash_table_key(cur_succ, -1);

				// Check whether cur_succ already belongs to the solution or not
				cur_value = (char*)g_hash_table_lookup(mapping_table, cur_key);
				if(cur_value == NULL) { // new state in solution
					good_succ = cur_succ;
				}
				else { // existing state
					found = TRUE;
					free_tuple_full(cur_succ);
					break;
				}
				free(cur_key);
			}
			else {
				free_tuple_full(cur_succ);
			}
		}
		else { //t belongs to P_I
			//if(is_losing(cur_succ, losing_PO, losing_PI) == FALSE) { // cur_succ is not losing?
				GList *curlink = max_succ->incomparable_elements;
				found = FALSE;
				while(curlink != NULL) { // Among the maximal successors of t, find one which is greater than cur_succ
					if(compare_tuples(cur_succ, curlink->data) == TRUE) {
						cur_key = new_hash_table_key(curlink->data, -1);

						// Check whether cur_succ already belongs to the solution or not
						cur_value = (char*)g_hash_table_lookup(mapping_table, cur_key);
						if(cur_value == NULL) { // new state in solution
							update_winning_positions(clone_tuple(curlink->data), alphabet, winning_positions, mapping_table, losing_PO, losing_PI, passed);
						}
						free(cur_key);
						found = TRUE; //found a state to reach when P_I plays the i-th letter of its alphabet
						break;
					}
					curlink = curlink->next;
				}
				free_tuple_full(cur_succ);
				if(found == FALSE) { // Impossible?
					printf("add_state_to_solution: no succ for P_I in maximal succ\n");
					exit(0);
				}
			/*}
			else { // Impossible?
				printf("add_state_to_solution: succ losing for P_I\n");
				exit(0);
			}*/
		}
	}
	if(t->cf->player == P_I) {
		free_antichain_full(max_succ, (void*)free_tuple_full);
	}
	if(t->cf->player == P_O && found == FALSE) { // Impossible?
		update_winning_positions(good_succ, alphabet, winning_positions, mapping_table, losing_PO, losing_PI, passed);
	}
}
コード例 #5
0
/** OTFUR algorithm **/
otfur_result*
otfur(antichain *safety_game_PO, antichain *safety_game_PI, GNode* cfinfo, alphabet_info *alphabet, char starting_player, int dimension, int* max_credit) {
	clock_t start_time = clock();

	// Structures initialization
	GHashTable *succ_to_visit = g_hash_table_new_full(hash_key, compare_keys, free, NULL);
	GHashTable *passed = g_hash_table_new_full(hash_key, compare_keys, (GDestroyNotify)free_hash_table_key, free);
	GHashTable *depend = g_hash_table_new_full(hash_key, compare_keys, free, NULL);
	//GList *trash = NULL;

	GList *waiting = NULL;
	antichain *losing_PO = new_antichain();
	antichain *losing_PI = new_antichain();

	// Build initial tuple
	tuple *s_ini = build_initial_tuple(cfinfo, dimension, max_credit);

	// if s_ini belongs to the system and all its successors are unsafe, s_ini is losing
	if((starting_player == P_O && has_successor_in_safety_game(s_ini, alphabet, safety_game_PI) == FALSE)/* ||
			(starting_player == P_I && has_successor_not_in_safety_game(s_ini, alphabet, safety_game_PO) == TRUE)*/) { // To avoid k differences between forward and backward algorithms
		add_to_losing(s_ini, losing_PO, losing_PI);
	} // else, explore its successors
	else {
		waiting = add_to_waiting(s_ini, alphabet, safety_game_PO, safety_game_PI, losing_PO, losing_PI, waiting, succ_to_visit, passed);
		add_to_passed(s_ini, passed);
	}

	safety_game_edge *cur_edge;
	char cur_losing;
	int nb_cf_passed = 1;
	int nb_iter = 0;
	antichain* cur_safety_game;
	while(waiting != NULL && is_losing(s_ini, losing_PO, losing_PI) == FALSE) {
		nb_iter++;
		GList *last_link = g_list_last(waiting);
		cur_edge = (safety_game_edge*)last_link->data;
		waiting = remove_last(waiting);
		if(is_losing(cur_edge->from, losing_PO, losing_PI) == FALSE) { // If s is not losing
			if(is_passed(cur_edge->to, passed) == FALSE) { // If s' is not passed
				add_to_passed(cur_edge->to, passed);
				nb_cf_passed++;
				if(is_losing(cur_edge->to, losing_PO, losing_PI) == TRUE) { // If s' is losing -> add e for reevaluation
					//waiting = g_list_append(waiting, clone_safety_game_edge(cur_edge));
					waiting = g_list_append(waiting, cur_edge);
				}
				// Basic case: if s' belongs to P_O and has no successor safe non losing, add it to losing
				// Put the same test for P_I to avoid k differences between forward and backward algorithms
				else if(cur_edge->to->cf->player == P_O && has_successor_non_losing_in_safety_game(cur_edge->to, alphabet, losing_PO, losing_PI, safety_game_PI) == FALSE) {
					//waiting = g_list_append(waiting, clone_safety_game_edge(cur_edge));
					waiting = g_list_append(waiting, cur_edge);
					add_to_losing(cur_edge->to, losing_PO, losing_PI);
				}
				else { // else, explore its successors
					add_to_depend(cur_edge->to, cur_edge, depend);
					waiting = add_to_waiting(cur_edge->to, alphabet, safety_game_PO, safety_game_PI, losing_PO, losing_PI, waiting, succ_to_visit, passed);
				}
			}
			else { // s' is passed
				if(cur_edge->from->cf->player == P_O) { // s belongs to P_O
					if(is_losing(cur_edge->to, losing_PO, losing_PI) == FALSE) { // if s' is not losing, add e to the dependencies of s'
						add_to_depend(cur_edge->to, cur_edge, depend);
					}
					else { // if s' is losing, and if there is no more successor of s non losing to visit, s is losing -> add its dependencies to waiting
						if(has_one_succ_to_visit_non_losing(cur_edge->from, succ_to_visit, losing_PO, losing_PI) == FALSE) {
							add_to_losing(cur_edge->from, losing_PO, losing_PI);
							waiting = g_list_concat(waiting, get_dependencies(cur_edge->from, depend));
						}
						else { // if there is still at least a successor non passed non losing, add it to waiting
							waiting = g_list_append(waiting, get_first_successor_passed_non_losing(cur_edge->from, succ_to_visit, passed, losing_PO, losing_PI));
						}
					}
				}
				else { // s belongs to P_I
					// reevaluation
					if(is_losing(cur_edge->to, losing_PO, losing_PI) == TRUE) {
						cur_losing = TRUE;
					}
					else {
						cur_losing = reevaluation(cur_edge->from, alphabet, losing_PO, losing_PI);
					}

					// if s is losing, add its dependencies to waiting
					if(cur_losing == TRUE) {
						add_to_losing(cur_edge->from, losing_PO, losing_PI);
						waiting = g_list_concat(waiting, get_dependencies(cur_edge->from, depend));
					}

					// if s' is not losing, add e to its dependencies list
					if(is_losing(cur_edge->to, losing_PO, losing_PI) == FALSE) {
						add_to_depend(cur_edge->to, cur_edge, depend);
					}
				}
				//trash = g_list_append(trash, cur_edge->to);
			}
		}
		else { // if s is losing, add its dependencies to waiting
			//free_tuple_full(cur_edge->to);
			waiting = g_list_concat(waiting, get_dependencies(cur_edge->from, depend));
		}
	}
	float otfur_time = (clock() - start_time) * 1e-6;

	// Extract the solution from passed and losing
	start_time = clock();
	safety_game* sg = compute_winning_positions(losing_PO, losing_PI, passed, build_initial_tuple(cfinfo, dimension, max_credit), alphabet, nb_cf_passed);
	float winning_positions_computation_time = (clock() - start_time) * 1e-6;

	// Free memory
	GList *curlink = waiting;
	//while(curlink != NULL) {
	//	free_safety_game_edge(curlink->data);
	//	curlink = curlink->next;
	//}
	g_list_free(waiting);
	/*curlink = trash;
	while(curlink != NULL) {
		free_tuple_full(curlink->data);
		curlink = curlink->next;
	}
	g_list_free(trash);*/
	//g_hash_table_destroy(passed); // this one is not correct !
	g_hash_table_foreach(depend, free_depend, NULL);
	g_hash_table_destroy(depend);
	g_hash_table_foreach(succ_to_visit, free_succ_to_visit, NULL);
	g_hash_table_destroy(succ_to_visit);

	// Build result
	otfur_result *res = (otfur_result*)malloc(sizeof(otfur_result));
	res->winning_positions = sg;
	res->otfur_time = otfur_time;
	res->winning_positions_computation_time = winning_positions_computation_time;
	res->nb_cf_passed = nb_cf_passed;
	res->nb_iter = nb_iter;

	return res;
}