Example #1
0
/**
 * @brief Move generator performance test function.
 *
 * @param board
 * @param depth
 * @param global_stats statistics
 */
static void count_game(const Board *board, const int depth, GameStatistics *global_stats)
{
	GameStatistics stats = GAME_STATISTICS_INIT;
	unsigned long long moves;
	int x;
	Board next[1];

	if (depth == 1) {
		moves = get_moves(board->player, board->opponent);
		stats.n_moves = stats.max_mobility = stats.min_mobility = bit_count(moves);
		if (moves == 0) {
			if (can_move(board->opponent, board->player)) {
				stats.n_passes = 1;
			} else {
				const int n_player = bit_count(board->player);
				const int n_opponent = bit_count(board->opponent);
				if (n_player > n_opponent) stats.n_wins = 1;
				else if (n_player == n_opponent) stats.n_draws = 1;
				else stats.n_losses = 1;
			}
		}
	} else {
		moves = get_moves(board->player, board->opponent);
		if (moves) {
			foreach_bit (x, moves) {
				board_next(board, x, next);
				count_game(next, depth - 1, &stats);
			}
		} else {
Example #2
0
/**
* is_a_winner
* input : player_e turn
* output : TRUE/FALSE
* functionality : returns TRUE if given player is the winner of the game else return FALSE
*/
bool is_a_winner(player_e turn){
	bool winner = FALSE;
	coordinate_t* temp_king, *temp_man;

	if (turn == COMPUTER)
	{
		temp_king = creat_linkedList_pointer(KING, USER);
		temp_man = creat_linkedList_pointer(MAN, USER);
	}
	else
	{
		temp_king = creat_linkedList_pointer(KING, COMPUTER);
		temp_man = creat_linkedList_pointer(MAN, COMPUTER);
	}
	if ((temp_king == NULL) && (temp_man == NULL)) /* enemy don't have any tools.*/
	{
		winner = TRUE;
	}
	else
	{
		get_moves(turn^1);
		if (paths_arr[0] == NULL)
		{
			winner = TRUE;
		}
	}

	return winner;
}
Example #3
0
/*
* Tries to make a move for r1, if it can't, generate more moves
* */
void move(path *r1, path *r2) {
	int ret = -1;
	
	// Try to reserve a move
	if (r1->moves_x->size() > 0) { //&& !(r1->moves_x->front() == r2->curr_x))
		ret = robot->reserveMap(r1->moves_x->front(), r1->moves_y->front());
		printf("Ret: %d: %d %d \n", ret, r1->moves_x->front(), r1->moves_y->front());
	}
	
	if (0 == ret) {
		// Consume the move we are making from the queue
		r1->curr_x = r1->moves_x->front();
		r1->curr_y = r1->moves_y->front();
		r1->moves_x->erase(r1->moves_x->begin());
		r1->moves_y->erase(r1->moves_y->begin());
		
		// Move to cell if we are not debugging
		robotPose->moveToCell(r1->curr_x, r1->curr_y);
	
		// Sleep if we are debugging
		//sleep(1);
		
		robot->updateMap(r1->curr_x, r1->curr_y);
		
		//if (maze[r1->curr_y][r1->curr_x] > 0) {
			//r1_score += maze[r1->curr_y][r1->curr_x];
			//maze[r1->curr_y][r1->curr_x] = 0;
		//}
	}
	// Give up and try generating new moves
	else {
		get_moves(r1, r2);
		move(r1, r2);
	}
}
Example #4
0
/* Naively choose the move that will shrink the most dots. */
mask_t choose_move_greedy(grid_t grid, int allow_shrinkers, int *no_moves) {
    mask_t move = EMPTY_MASK;
    int i, num_dots, max_dots = -1;

    int num_moves;
    move_list_t moves;
    get_moves(grid, allow_shrinkers, &num_moves, moves);

    *no_moves = 0;
    if (SHOULD_SHRINK_RANDOM(num_moves, allow_shrinkers)) {
        *no_moves = 1;
        return random_mask();
    }

    for (i = 0; i < num_moves; i++) {
        grid_t new_grid;
        memcpy(new_grid, grid, sizeof(grid_t));
        num_dots = apply_move(new_grid, moves[i]);
        if (num_dots > max_dots) {
            max_dots = num_dots;
            move = moves[i];
        }
    }
    return move;
}
/*
* @brief initiates the forest generation, setting the max number of tiles(lifespan) that can be set to road
* sets the possible moves and send it to tile_forest_walk to be evaluated
* @param int tile index to start the forest walk. 
*/
void tile_forest_gen(int start)
{
	int i = start;
	int done = false;
	int lifespan = TOTAL_TILES / 20;
	//-1 means can't move to that node
	tile_list[i].mType = TILE_ROAD;
	dest_tile_list[i].mType = TILE_ROAD;
	++call_stack;

	while( 0 < lifespan--)
	{
		int moves[4] = {i-1, i+1, i-TOTAL_TILES_X, i + TOTAL_TILES_X}; // left,right,up,down a tile on map
		int j;

		get_moves(moves, 4, i);//4 directions
		i = tile_forest_walk(moves);
		//update scores here
		//road tiles have heur score +10
		//adjacent tiles to road have score +3
		tile_list_scores[i] += 10;
		moves[0] = i - 1;
		moves[1] = i + 1;
		moves[2] = i - TOTAL_TILES_X;
		moves[3] = i + TOTAL_TILES_X;
		get_moves(moves, 4, i);//4 directions
		for(j = 0; j < 4; j++)
		{
			if(moves[j] == -1)
			{
				continue;
			}
			tile_list_scores[moves[j]] += 3; 
		}
		tile_list[i].mType = TILE_ROAD;
		dest_tile_list[i].mType = TILE_ROAD;
	}
}
Example #6
0
/* heuristic = score ** uncertainty_of_board
 *   where uncertainty_of_board = (sum of certainty_of_dots) / num_dots
 *         uncertainty_of_dot | 1/4 if shrunk by cycle
 *                            | 1/5 if shrunk by a regular move
 *                            | 1   otherwise
 */
void _choose_move(grid_t grid, int allow_shrinkers, int turns_remaining, int certainty, float *value, mask_t *move, int *no_moves) {
    float best_value = -1;
    mask_t best_move = EMPTY_MASK;

    int i, num_moves;
    move_list_t moves;

    get_moves(grid, allow_shrinkers, &num_moves, moves);

    if (certainty == 720 && SHOULD_SHRINK_RANDOM(num_moves, allow_shrinkers)) {
        *move = random_mask();
        *value = num_dots(*move);
        *no_moves = 1;
        return;
    }

    for (i = 0; i < num_moves; i++) {
        int score;
        float value;
        grid_t new_grid;

        if (turns_remaining > 1 || HAS_CYCLE(moves[i])) {
            memcpy(new_grid, grid, sizeof(grid_t));
            score = apply_move(new_grid, moves[i]);
        } else {
            score = num_dots(moves[i]);
        }

        value = pow(score, certainty / 720.0);

        if (turns_remaining > 1) {
            int next_certainty = certainty - score * (HAS_CYCLE(moves[i]) ? 15 : 16);
            float next_value;
            mask_t next_move;
            _choose_move(new_grid, allow_shrinkers, turns_remaining - 1, next_certainty, &next_value, &next_move, NULL);
            value += next_value;
        }

        if (value > best_value) {
            best_value = value;
            best_move = moves[i];
        }
    }

    *value = best_value;
    *move = best_move;
}
Example #7
0
int setNewGame(tGame * game)
{

	if (game->gametype != GAMETYPE_CAMPAIGN)
	{
		getDim(game);
		getLevel(game);
	}
	else
	{
		int campaign_rows = game->campaign[game->campaign_level-1].rows;
		int campaign_columns = game->campaign[game->campaign_level-1].columns;
		int campaign_level = game->campaign[game->campaign_level-1].level;

		if (campaign_rows > MAX_ROWS || campaign_columns > MAX_COLUMNS)
		{	
			printf("El nivel actual posee un tablero muy grande, se pasara al proximo nivel");
			game->campaign_level++;
			return FALSE;
		}
		
		game->visualboard.rows = game->hiddenboard.rows = campaign_rows;
		game->visualboard.columns = game->hiddenboard.columns = campaign_columns;
		game->level = campaign_level;
	}
	setGameMinesNumber(game);
 	game->undos = get_undos(game->level);
 	
 	/* Moves */
 	if (game->gametype == GAMETYPE_INDIVIDUAL_NOLIMIT)
 		game->moves = UNLIMITED_MOVES;
 	else
 		game->moves = get_moves(game->undos, game->mines);
 	
 	game->mines_left = game->mines;
 	game->sweeps_left = (game->visualboard.rows * game->visualboard.columns) - game->mines;
 	game->flags_left = game->mines;
 	game->gamestate = GAMESTATE_DEFAULT; 

 	if (!CreateHiddenVisualBoard(game))
 		return MALLOC_ERR;

 	/* Ready to play */
 	return TRUE;
}
Example #8
0
/** returns an int representing the score for the previously
  * executed move (that caused the a_board configuration),
  * according to the scoring function and depending on the depth.
  * this is a recursive function. */
int minmax(char a_board[BOARD_SIZE][BOARD_SIZE], int minim, int next_color, int depth, int alpha, int beta)
{	
	int true_color =  (minim) ? !next_color : next_color;
	move *moves = NULL;
	move *temp = NULL;
	int mini_score = INF_SCORE;
	int maxi_score = -INF_SCORE;
	// recursion ends
	if ( depth == MINIMAX_DEPTH )	return score_board(a_board, true_color);
	if ( board_cnt > TOO_MUCH ) return score_board(a_board, true_color); // (just to be safe)
	moves = get_moves(a_board, next_color);	//get the moves of the other player
	if ( moves == NULL )
	{
		int current_score = score_board(a_board, next_color);
		if (current_score == TIE_SCORE) return TIE_SCORE;
		if(minim) return WIN_SCORE;
		else return LOOSE_SCORE;
	}
	temp = moves;	//initialize temp
	while ( temp != NULL )
	{
		int temp_score;
		char board_copy[BOARD_SIZE][BOARD_SIZE];
		memcpy(board_copy, a_board, sizeof(board_copy));
		board_cnt++;
		DO_DEBUG2(if (board_cnt%100000 == 0) printf("%d millions of boards.\n", board_cnt/1000000); fflush(stdout);) 
		do_move(board_copy, temp); // now the board copy is updated 
		temp_score = minmax(board_copy, !minim, !next_color, depth+1, alpha, beta);
		
		if ( temp_score > maxi_score )
		{
			maxi_score = temp_score;
			if ( !minim ) alpha = maxi_score;
		}
		if ( temp_score < mini_score )
		{
			mini_score = temp_score;
			if ( minim ) beta = mini_score;
		}
		if ( alpha > beta ) break;
		temp = temp->next;
	}
Example #9
0
/**
* is_legal_move
* input : path_t* user_input_path
* output : TRUE/FALSE
* functionality : returns TRUE if the move is legal else return FALSE
*/
bool is_legal_move(path_t* user_input_path)
{
	bool comparison;
	int i;
	comparison = FALSE;
	get_moves(Turn);
	if (paths_number == 0)
	{
		return comparison;
	}
	else
	{
		for(i = 0; i < paths_number; i++)
		{
			comparison = compare_two_paths(paths_arr[i], user_input_path);
			if (comparison)
			{
				break;
			}
		}
	}
	return comparison;
}
Example #10
0
/**
 * Process a monster
 *
 * In several cases, we directly update the monster lore
 *
 * Note that a monster is only allowed to "reproduce" if there
 * are a limited number of "reproducing" monsters on the current
 * level.  This should prevent the level from being "swamped" by
 * reproducing monsters.  It also allows a large mass of mice to
 * prevent a louse from multiplying, but this is a small price to
 * pay for a simple multiplication method.
 *
 * XXX Monster fear is slightly odd, in particular, monsters will
 * fixate on opening a door even if they cannot open it.  Actually,
 * the same thing happens to normal monsters when they hit a door
 *
 * In addition, monsters which *cannot* open or bash down a door
 * will still stand there trying to open it...  XXX XXX XXX
 *
 * Technically, need to check for monster in the way combined
 * with that monster being in a wall (or door?) XXX
 */
static void process_monster(struct chunk *c, struct monster *mon)
{
	struct monster_lore *lore = get_lore(mon->race);

	bool did_something = false;

	int i;
	int dir = 0;
	bool stagger = false;
	char m_name[80];

	/* Get the monster name */
	monster_desc(m_name, sizeof(m_name), mon, MDESC_CAPITAL | MDESC_IND_HID);

	/* Try to multiply - this can use up a turn */
	if (process_monster_multiply(c, mon))
		return;

	/* Attempt to cast a spell */
	if (make_attack_spell(mon)) return;

	/* Work out what kind of movement to use - AI or staggered movement */
	if (!process_monster_should_stagger(mon)) {
		if (!get_moves(c, mon, &dir)) return;
	} else {
		stagger = true;
	}

	/* Process moves */
	for (i = 0; i < 5 && !did_something; i++) {
		int oy = mon->fy;
		int ox = mon->fx;

		/* Get the direction (or stagger) */
		int d = (stagger ? ddd[randint0(8)] : side_dirs[dir][i]);

		/* Get the destination */
		int ny = oy + ddy[d];
		int nx = ox + ddx[d];

		/* Check if we can move */
		if (!process_monster_can_move(c, mon, m_name, nx, ny, &did_something))
			continue;

		/* Try to break the glyph if there is one.  This can happen multiple
		 * times per turn because failure does not break the loop */
		if (square_iswarded(c, ny, nx) &&
			!process_monster_glyph(c, mon, nx, ny))
			continue;

		/* The player is in the way. */
		if (square_isplayer(c, ny, nx)) {
			/* Learn about if the monster attacks */
			if (mflag_has(mon->mflag, MFLAG_VISIBLE))
				rf_on(lore->flags, RF_NEVER_BLOW);

			/* Some monsters never attack */
			if (rf_has(mon->race->flags, RF_NEVER_BLOW))
				continue;

			/* Otherwise, attack the player */
			make_attack_normal(mon, player);

			did_something = true;
			break;
		} else {
			/* Some monsters never move */
			if (rf_has(mon->race->flags, RF_NEVER_MOVE)) {
				/* Learn about lack of movement */
				if (mflag_has(mon->mflag, MFLAG_VISIBLE))
					rf_on(lore->flags, RF_NEVER_MOVE);

				return;
			}
		}

		/* A monster is in the way, try to push past/kill */
		if (square_monster(c, ny, nx)) {
			did_something = process_monster_try_push(c, mon, m_name, nx, ny);
		} else {
			/* Otherwise we can just move */
			monster_swap(oy, ox, ny, nx);
			did_something = true;
		}

		/* Scan all objects in the grid, if we reached it */
		if (mon == square_monster(c, ny, nx)) {
			monster_desc(m_name, sizeof(m_name), mon,
						 MDESC_CAPITAL | MDESC_IND_HID);
			process_monster_grab_objects(c, mon, m_name, nx, ny);
		}
	}

	if (did_something) {
		/* Learn about no lack of movement */
		if (mflag_has(mon->mflag, MFLAG_VISIBLE))
			rf_on(lore->flags, RF_NEVER_MOVE);

		/* Possible disturb */
		if (mflag_has(mon->mflag, MFLAG_VISIBLE) &&
			mflag_has(mon->mflag, MFLAG_VIEW) && OPT(player, disturb_near))
			disturb(player, 0);		
	}

	/* Hack -- get "bold" if out of options */
	if (!did_something && mon->m_timed[MON_TMD_FEAR])
		mon_clear_timed(mon, MON_TMD_FEAR, MON_TMD_FLG_NOTIFY, false);

	/* If we see an unaware monster do something, become aware of it */
	if (did_something && mflag_has(mon->mflag, MFLAG_UNAWARE))
		become_aware(mon);
}