Пример #1
0
void Gene::do_sim(){
  Snake s;
  Snake::mov_v v;
  do{
    if(t_stack.empty()){
      v = get_move(&s,t_tr);
    }else{
      v = get_move(&s,t_stack.top());
      t_stack.pop();
    }
    s.print_b();
    usleep(50000);
  }while(s.move(v));
}
Пример #2
0
void	puissance4(t_grid *grid)
{
	int		end;
	int		move;
	int		player;
	int		result;
	int		nbcoup;

	end = 0;
	move = -1;
	player = (ft_rand() % 2) + 1;
	result = 0;
	nbcoup = grid->width * grid->height;
	while (end == 0 && nbcoup > 0)
	{
		put_prompt(player, grid);
		if ((move = get_move(player, grid)) == -1)
			return ;
		if ((result = put_tocken(grid, move, player)) == 0)
		{
			player = (player == 1 ? 2 : 1);
			nbcoup--;
		}
		else if (result == 2)
		{
			victory(player, grid);
			end = 1;
		}
	}
	if (nbcoup == 0)
		ft_printf("Draw\n");
}
Пример #3
0
static void update_best_move_history(position_t *p, int index_of_best,
                                     sortable_move_t* lst, int count) {
  tbassert(ENABLE_TABLES, "Tables weren't enabled.\n");

  int color_to_move = color_to_move_of(p);

  for (int i = 0; i < count; i++) {
    move_t   mv  = get_move(lst[i]);
    ptype_t  pce = ptype_mv_of(mv);
    rot_t    ro  = rot_of(mv);  // rotation
    square_t fs  = from_square(mv);
    int      ot  = ORI_MASK & (ori_of(p->board[fs]) + ro);
    square_t ts  = to_square(mv);

    int  s = best_move_history[BMH(color_to_move, pce, ts, ot)];

    if (index_of_best == i) {
      s = s + 11200;  // number will never exceed 1017
    }
    s = s * 0.90;  // decay score over time

    tbassert(s < 102000, "s = %d\n", s);  // or else sorting will fail

    best_move_history[BMH(color_to_move, pce, ts, ot)] = s;
  }
}
Пример #4
0
__irq void EXTI15_10_IRQHandler(void) {
	if(EXTI_GetITStatus(EXTI_Line11) != RESET) {
		recorded_move = get_move();
		EXTI_ClearITPendingBit(EXTI_Line11);
	}

}
Пример #5
0
// Obtain a sorted move list.
static int get_sortable_move_list(searchNode *node, sortable_move_t * move_list,
                         int hash_table_move) {
  // number of moves in list
  int num_of_moves = generate_all_opt(&(node->position), move_list, false);

  color_t fake_color_to_move = color_to_move_of(&(node->position));

  move_t killer_a = killer[KMT(node->ply, 0)];
  move_t killer_b = killer[KMT(node->ply, 1)];

  // sort special moves to the front
  for (int mv_index = 0; mv_index < num_of_moves; mv_index++) {
    move_t mv = get_move(move_list[mv_index]);
    if (mv == hash_table_move) {
      set_sort_key(&move_list[mv_index], SORT_MASK);
    } else if (mv == killer_a) {
      set_sort_key(&move_list[mv_index], SORT_MASK - 1);
    } else if (mv == killer_b) {
      set_sort_key(&move_list[mv_index], SORT_MASK - 2);
    } else {
      ptype_t  pce = ptype_mv_of(mv);
      rot_t    ro  = rot_of(mv);   // rotation
      square_t fs  = from_square(mv);
      int      ot  = ORI_MASK & (ori_of(node->position.board[fs]) + ro);
      square_t ts  = to_square(mv);
      set_sort_key(&move_list[mv_index],
                   best_move_history[BMH(fake_color_to_move, pce, ts, ot)]);
    }
  }
  return num_of_moves;
}
Пример #6
0
static int negamax_algo(struct chessboard *c, int color, int depth, int alpha, int beta)
{
	struct move_list *l;
	struct raw_move m;
	int n;
	int val, best_val = INT_MIN;

	if (!depth)
		return !color ? calculate_board_heuristic(c) : -calculate_board_heuristic(c);

	l = allocate_move_list();
	for (int i = 0; i < 16; i++) {
		n = enumerate_moves(c, (color << 4) | i, l);
		expanded_moves += n;

		for (int j = 0; j < n; j++) {
			get_move(l, j, &m.sx, &m.sy, &m.dx, &m.dy);

			execute_raw_move(c, &m);
			evaluated_moves++;

			val = -negamax_algo(c, !color, depth - 1, -beta, -alpha);

			unwind_raw_move(c, &m);

			best_val = max(best_val, val);
			alpha = max(alpha, val);
			if (alpha >= beta)
				break;
		}
	}

	free_move_list(l);
	return best_val;
}
Пример #7
0
Snake::mov_v Gene::get_move(Snake * s, gene_t_p t){
  switch(t->mov){
  case l:
  case front:
  case r:
    return (Snake::mov_v)t->mov;
  case if_f:
    if((s->*(t->p))()){
      return get_move(s,t->lt);
    }else{
      return get_move(s,t->rt);
    }
  case proc:
    t_stack.push(t->rt);
    return get_move(s,t->lt);
  }
}
Пример #8
0
/* -----------------------------------------------------
	This gets all the child moves
	and compares them to a string of moves

	ALL the moves must match
	----------------------------------------------------*/
void check_contains_moves(CHESS_STATE *current_state, char *expected_moves)
{
    CHESS_STATE *child_states;

    char buffer[100] = {0};

    strcpy(buffer,expected_moves);
    generate_moves(current_state);

    char *next_expected_move = strtok(buffer, ",");

    while(next_expected_move != NULL)
    {
        char *move_text;
        int found = 0;

        for (child_states = current_state->child_head;
                child_states != NULL;
                child_states = child_states->next)
        {
            move_text = get_move(child_states,0);

            if (strcmp(move_text, next_expected_move)==0)
            {
                found=1;
                break;
            }
        }
        if (found==0)
        {
            printf("%s not found!\n",next_expected_move);
            for (child_states = current_state->child_head;
                    child_states!=NULL;
                    child_states = child_states->next)
            {
                move_text=get_move(child_states,0);
                printf("%s ",move_text);
            }
            exit(1);
        }

        next_expected_move = strtok(NULL,",");
    }
    delete_nodes(current_state);
}
int main()
{
	int i, j;
	for (i = 0; i < 8; ++i)
		for (j = 0; j < 8; ++j)
		scanf("%d", &board[i][j]);
    get_move(1, 6); /*调用AI,得到我的结果,‘1’表示是‘我’走这步,‘5’表示我的搜索深度是5*/
    printf("%d %d\n", best_x, best_y);
    return 1;
}
Пример #10
0
static gboolean
game_handle_io (GGZMod * mod)
{
  int op = -1;

  fd = ggzmod_get_server_fd (mod);

  // Read the fd
  if (ggz_read_int (fd, &op) < 0) {
    ggz_error_msg ("Couldn't read the game fd");
    return FALSE;
  }

  switch (op) {
  case GN_MSG_SEAT:
    get_seat ();
    break;
  case GN_MSG_PLAYERS:
    get_players ();
    break;

  case GN_MSG_START:
    gtk_notebook_set_current_page (GTK_NOTEBOOK (notebook), MAIN_PAGE);
    new_game ();
    break;

  case GN_MSG_SYNC:
    get_sync ();
    break;

  case GN_MSG_MOVE:
    get_move ();
    break;

  case GN_MSG_SETTINGS:
    get_settings ();
    break;

  case GN_MSG_BONI:
    get_boni ();
    break;

  case GN_MSG_NOBONI:
    get_noboni ();
    break;

  default:
    ggz_error_msg ("Incorrect opcode   %d \n", op);
    break;
  }

  return TRUE;
}
Пример #11
0
double Gene::get_fitness(){
  len = time = 0.0;
  for(int i=0;i<REP_S;i++){
    Snake s;
    Snake::mov_v v;
    do{
      if(t_stack.empty()){
	v = get_move(&s,t_tr);
      }else{
	v = get_move(&s,t_stack.top());
	t_stack.pop();
      }
      //s.print_b();
    }while(s.move(v));
    len += (double)s.get_len();
    time += (double)s.get_time();
  }
  len /= (double)REP_S;
  time /= (double)REP_S;
  return pow(W_POW,time/(len-START_LEN+1.0)*W_TIME + len*W_LEN) + CON;
}
Пример #12
0
void test_mate_in_two()
{
	struct position *pos = allocate_board();
	consume_fen_notation(MATE_IN_TWO, pos);

    struct search_info si;

    memset(&si, 0, sizeof(struct search_info));

    si.depth = 4;
    search_positions(pos, &si, 64000000);

    // *** exclude the score ***
    mv_bitmap h7h8 = get_move(MOVE(h7, h8, NO_PIECE, NO_PIECE, 0));
    mv_bitmap g7h8 = get_move(MOVE(g7, h8, W_ROOK, NO_PIECE, MFLAG_CAPTURE));
    mv_bitmap h1h8 = get_move(MOVE(h1, h8, B_BISHOP, NO_PIECE, MFLAG_CAPTURE));

    mv_bitmap pv_line_h7h8 = get_move(get_pvline(pos, 0));
    mv_bitmap pv_line_g7h8 = get_move(get_pvline(pos, 1));
    mv_bitmap pv_line_h1h8 = get_move(get_pvline(pos, 2));

    //printf("PV g7h8 ->%s\n", print_move(pv_line_g7h8));
    //printf("PV h1h8 ->%s\n", print_move(pv_line_h1h8));

    assert_true(h7h8 == pv_line_h7h8);
    assert_true(g7h8 == pv_line_g7h8);
    assert_true(h1h8 == pv_line_h1h8);

}
Пример #13
0
/* ---------------------------------------------------------------------------------------
	CHESS_STATE *check_move(CHESS_STATE *parent_state, CHAR *move)
	
	purpose: scans the child moves of a parent state, and if the 
	         supplied movetext (which can be either algebraic chess
	         notation, or move ui text) matches the move text of the 
	         child state, the child state is returned. else null is returned.
   --------------------------------------------------------------------------------------- */
CHESS_STATE *check_move(CHESS_STATE *parent_state, char *move)
{
	CHESS_STATE *child = parent_state->child_head;

	while (child !=NULL)
	{
		if (strcmp(get_move(child,0),move)==0)
			return child;
		else
		{
			char move_text_ui_buffer[20] = {0};
			strcpy(move_text_ui_buffer,get_move(child,1));
			// get the first move of the move text ui
			// this is the 'main move' and is what is 
			// checked with user's IN move.
			char *main_ui_move = strtok(move_text_ui_buffer, " ");	
			if (strcmp(main_ui_move, move)==0)
				return child;
		}
		child = child->next;
	}
	return NULL;
}
Пример #14
0
void		add_move(char **result, int move)
{
	static char	mvs[][4] = {"sa", "sb", "ss", "pa", "pb", "ra", "rb", "rr", \
							"rra", "rrb", "rrr"};
	int			i;
	char		*tmp;

	i = get_move(move);
	tmp = *result;
	if (**result)
	{
		*result = ft_strjoin(*result, " ");
		free(tmp);
		tmp = *result;
	}
	*result = ft_strjoin(*result, mvs[i]);
	free(tmp);
}
Пример #15
0
/* Returns sx|sy|dx|dy in an integer byte-by-byte from least to most
 * significant, indicating which move should be made next.
 *
 * We seperate the initial iteration of negamax out like this to track the
 * actual move associated with the best score. Doing so during the
 * deeper iterations is a waste of time. */
unsigned int calculate_move(struct chessboard *c, int color, int depth)
{
	struct move_list *l;
	int n, fbsx = -1, fbsy = -1, fbdx = -1, fbdy = -1;
	int val, best_val = INT_MIN, alpha = INT_MIN, beta = INT_MAX;
	struct raw_move m;
	struct timespec *t;

	expanded_moves = 0;
	evaluated_moves = 0;

	t = start_timer();
	l = allocate_move_list();
	for (int i = 0; i < 16; i++) {
		n = enumerate_moves(c, (color << 4) | i, l);
		expanded_moves += n;

		for (int j = 0; j < n; j++) {
			get_move(l, j, &m.sx, &m.sy, &m.dx, &m.dy);
			execute_raw_move(c, &m);
			evaluated_moves++;

			val = -negamax_algo(c, !color, depth - 1, -beta, -alpha);

			alpha = max(alpha, val);
			if (val > best_val) {
				best_val = val;
				fbsx = m.sx;
				fbsy = m.sy;
				fbdx = m.dx;
				fbdy = m.dy;
			}

			debug("Move %d/%d for piece %d (%d,%d) => (%d,%d) has heuristic value %d\n", j + 1, n, (color << 4) | i, m.sx, m.sy, m.dx, m.dy, val);
			unwind_raw_move(c, &m);
		}
	}
	free_move_list(l);
	expanded_moves += n;
	debug("Evaluated %luM/%luM expanded moves in %lu seconds\n", evaluated_moves / 1000000, expanded_moves / 1000000, get_timer_and_free(t) / 1000);

	return (fbsx) | (fbsy << 8) | (fbdx << 16) | (fbdy << 24);
}
Пример #16
0
int play(uint32_t goal)
{
    while (!reach_goal(goal)) {
        print_board();
        if (!SPACE)
            return 0;

        switch (get_move()) {
            case 'W':
            case 'w':
                up();
                new_item();
                break;
            case 'S':
            case 's':
                down();
                new_item();
                break;
            case 'A':
            case 'a':
                left();
                new_item();
                break;
            case 'D':
            case 'd':
                right();
                new_item();
                break;
            case 'C':
            case 'c':
                if (CHEAT)
                    cheat();
                break;
            case 'G':
            case 'g':
                if (CHEAT)
                    return 0;
                break;
        }
    }

    return 1;
}
Пример #17
0
int main()
{
    char board[8][8];
    int kx = 1, ky = 7;   // Starting location for knight
 
    printf("x: %d, y: %d\n", kx, ky);   
    srand(time(NULL));    // Seed the random number generator
    
    int tx, ty;           // Target location
    
    do
    {
        tx = rand() % 8;  // Pick random target
        ty = rand() % 8;
    } while (tx == kx && ty == ky);
    
    init_board(board);
    board[ty][tx] = 'G';    // Place goal and knight
    board[ky][kx] = 'K';
    
    print_board(board);
    
    int moves = 0;
    
    while (tx != kx || ty != ky)
    {
        char move = get_move();
        board[ky][kx] = '_';
        int ret = move_knight(&kx, &ky, move); 
        board[ky][kx] = 'K';
        if (!ret)
        {
            printf("Invalid move.\n");
        }
        else
        {
            print_board(board);
            moves++;
        }
    }
    printf("You won in %d moves!\n", moves);
}
Пример #18
0
int
main(int argc, char** argv){
	GAME_STATE game; /*ゲーム構造体*/
	int legal_move = 0; /*1なら合法手*/
	int finish = 0; /*1になるとゲームが終了となる*/

	/*ゲーム状態の初期化*/
	init(&game);
	/*ディスプレイに盤面を出力*/
	disp_board(&game);
	/*ループ*/
	while(finish != 1){
		legal_move = 0;
		while(legal_move != 1){
			if(game.teban == 1){
				get_move(&game); /*人間側*/
			}else{
				think_move(&game); /*コンピュータ側*/
			}
			/*その手が合法手かを判定*/
			legal_move = check_legal_move(&game);
		}

		/*手によって盤面の状態を変更する*/
		make_move(&game);
	
		/*ディスプレイに盤面を表示*/
		disp_board(&game);

		/*終局判定*/
		finish = check_finish_game(&game);

		/*手番を交代する*/
		change_teban(&game);
	}
	exit(0);
}
static score_t scout_search(searchNode *node, int depth,
                            uint64_t *node_count_serial) {
  // Initialize the search node.
  initialize_scout_node(node, depth);

  // check whether we should abort
  if (should_abort_check() || parallel_parent_aborted(node)) {
    return 0;
  }

  // Pre-evaluate this position.
  leafEvalResult pre_evaluation_result = evaluate_as_leaf(node, SEARCH_SCOUT);

  // If we decide to stop searching, return the pre-evaluation score.
  if (pre_evaluation_result.type == MOVE_EVALUATED) {
    return pre_evaluation_result.score;
  }

  // Populate some of the fields of this search node, using some
  //  of the information provided by the pre-evaluation.
  int hash_table_move = pre_evaluation_result.hash_table_move;
  node->best_score = pre_evaluation_result.score;
  node->quiescence = pre_evaluation_result.should_enter_quiescence;

  // Grab the killer-moves for later use.
  move_t killer_a = killer[KMT(node->ply, 0)];
  move_t killer_b = killer[KMT(node->ply, 1)];

  // Store the sorted move list on the stack.
  //   MAX_NUM_MOVES is all that we need.
  sortable_move_t move_list[MAX_NUM_MOVES];

  // Obtain the sorted move list.
  int num_of_moves = get_sortable_move_list(node, move_list, hash_table_move);

  int number_of_moves_evaluated = 0;


  // A simple mutex. See simple_mutex.h for implementation details.
  simple_mutex_t node_mutex;
  init_simple_mutex(&node_mutex);

  // Sort the move list.
  sort_incremental(move_list, num_of_moves, 0);
  
  moveEvaluationResult result;

  for (int mv_index = 0; mv_index < num_of_moves; mv_index++) {
    if (mv_index == 1) {
      sort_full(move_list, num_of_moves);
     // sortable_move_t new_move_list[MAX_NUM_MOVES];
      //memcpy(new_move_list, move_list, num_of_moves*sizeof(sortable_move_t));
     //: sort_incremental_full(move_list,num_of_moves);
    }
    // Get the next move from the move list.
    int local_index = number_of_moves_evaluated++;
    move_t mv = get_move(move_list[local_index]);

    if (TRACE_MOVES) {
      print_move_info(mv, node->ply);
    }

    // increase node count
    __sync_fetch_and_add(node_count_serial, 1);

    evaluateMove(&result, node, mv, killer_a, killer_b,
                 SEARCH_SCOUT,
                 node_count_serial);
    undo_move(&result.next_node, mv);

    if (result.type == MOVE_ILLEGAL || result.type == MOVE_IGNORE
        || abortf || parallel_parent_aborted(node)) {
      continue;
    }

    // A legal move is a move that's not KO, but when we are in quiescence
    // we only want to count moves that has a capture.
    if (result.type == MOVE_EVALUATED) {
      node->legal_move_count++;
    }

    // process the score. Note that this mutates fields in node.
    bool cutoff = search_process_score(node, mv, local_index, &result, SEARCH_SCOUT);

    if (cutoff) {
      node->abort = true;
      break;
    }
  }

  if (parallel_parent_aborted(node)) {
    return 0;
  }

  if (node->quiescence == false) {
    update_best_move_history(node->position, node->best_move_index,
                             move_list, number_of_moves_evaluated);
  }

  tbassert(abs(node->best_score) != -INF, "best_score = %d\n",
           node->best_score);

  // Reads node->position->key, node->depth, node->best_score, and node->ply
  update_transposition_table(node);

  return node->best_score;
}
Пример #20
0
/*-------------------------        Main           ---------------------*/
 int main(int argc, char *argv[]) {
 	/* Ensure enough arguments are passed */
 	if(argc < 3) {
 		fprintf(stderr, "Usage: %s host port.\n", argv[0]);
 		exit(EXIT_FAILURE);
 	}

 	/* Initialize a socket to communicate to the server */
	int socket_fd = initialize_client_socket(argv[1], atoi(argv[2]));

	/* Begin the connect4 game against the server. */
	/* The data structures required for this game */
	c4_t board;
	int move, n;
	init_empty(board);
	print_config(board);

    /* This loop does 2 moves each iteration. One for the
	 * human player and one for the server. 
	 */
	while ((move = get_move(board)) != EOF) {
	    /* process the person's move */
		if (do_move(board, move, YELLOW)!=1) {
			printf("Panic\n");
			break;
		}
		/* Send the move to the server */
		int converted_move = htonl(move);
		n = write(socket_fd, &converted_move, sizeof(converted_move));

		if(n < 0) {
			perror("Failed to write to socket.\n");
			break;
		}
		print_config(board);
		/* and did they win??? */
		if (winner_found(board) == YELLOW) {
			/* rats, the person beat us! */
			printf("Ok, you beat me, beginner's luck!\n");
			break;
		}
		/* was that the last possible move? */
		if (!move_possible(board)) {
			/* yes, looks like it was */
			printf("An honourable draw\n");
			break;
		}

		/* Ask the server for its move  */
		n = read(socket_fd, &move, sizeof(move));
        move = ntohl(move);
		if(n < 0) {
			perror("Failed to read from socket.\n");
			break;
		}

		/* pretend to be thinking hard */
		printf("Ok, let's see now....");
		sleep(1);
		/* then play the move */
		printf(" I play in column %d\n", move);
		if (do_move(board, move, RED)!=1) {
			printf("Panic\n");
			break;
		}
		print_config(board);
		/* and did we win??? */
		if (winner_found(board) == RED) {
			/* yes!!! */
			printf("I guess I have your measure!\n");
			break;
		}
		/* and did they win??? */
		if (winner_found(board) == YELLOW) {
			/* rats, the person beat us! */
			printf("Ok, you beat me, beginner's luck!\n");
			break;
		}
		/* Was that the last possible move? */
		if (!move_possible(board)) {
			/* yes, looks like it was */
			printf("An honourable draw\n");
			break;
		}
		/* otherwise, the game goes on */
	}
	printf("FINALMOVE=%d", move);
	printf("\n");
	close(socket_fd);
	return 0;
 }
Пример #21
0
/*
 * play_level:
 *	Let the player play the current level
 */
void
play_level(void)
{
	COORD	*cp;

	move(My_pos.y, My_pos.x);
	addch(PLAYER);
	refresh();
	for (cp = Robots; cp < &Robots[MAXROBOTS]; cp++) {
		if (cp->y < 0)
			continue;
		move(cp->y, cp->x);
		addch(ROBOT);
	}
	refresh();
#ifdef DEBUG
	standout();
	move(Min.y, Min.x);
	addch(inch());
	move(Max.y, Max.x);
	addch(inch());
	standend();
#endif /* DEBUG */
	flushinp();
	while (!Dead && Num_robots > 0) {
		move(My_pos.y, My_pos.x);
		if (!jumping())
			refresh();
		get_move();
		if (Field[My_pos.y][My_pos.x] != 0)
			Dead = TRUE;
		if (!Dead)
			move_robots();
		if (Was_bonus) {
			move(Y_PROMPT, X_PROMPT);
			clrtoeol();
			move(Y_PROMPT + 1, X_PROMPT);
			clrtoeol();
			Was_bonus = FALSE;
		}
	}

	/*
	 * if the player didn't die, add on the possible bonuses
	 */

	if (!Dead) {
		Was_bonus = FALSE;

		if (Level == Start_level && Start_level > 1) {
			move(Y_PROMPT, X_PROMPT);
			printw("Advance bonus: %d", S_BONUS);
			refresh();
			add_score(S_BONUS);
			Was_bonus = TRUE;
		}

		if (Wait_bonus != 0) {
			if (!Was_bonus)
				move(Y_PROMPT, X_PROMPT);
			else
				move(Y_PROMPT + 1, X_PROMPT);
			printw("Wait bonus: %d", Wait_bonus);
			refresh();
			add_score(Wait_bonus);
			Was_bonus = TRUE;
		}
	}
}
Пример #22
0
// Perform a Principle Variation Search
//   https://chessprogramming.wikispaces.com/Principal+Variation+Search
static score_t searchPV(searchNode *node, int depth, uint64_t *node_count_serial) {
  // Initialize the searchNode data structure.
  initialize_pv_node(node, depth);

  // Pre-evaluate the node to determine if we need to search further.
  leafEvalResult pre_evaluation_result = evaluate_as_leaf(node, SEARCH_PV);

  // use some information from the pre-evaluation
  int hash_table_move = pre_evaluation_result.hash_table_move;

  if (pre_evaluation_result.type == MOVE_EVALUATED) {
    return pre_evaluation_result.score;
  }
  if (pre_evaluation_result.score > node->best_score) {
    node->best_score = pre_evaluation_result.score;
    if (node->best_score > node->alpha) {
      node->alpha = node->best_score;
    }
  }

  // Get the killer moves at this node.
  move_t killer_a = killer[KMT(node->ply, 0)];
  move_t killer_b = killer[KMT(node->ply, 1)];


  // sortable_move_t move_list
  //
  // Contains a list of possible moves at this node. These moves are "sortable"
  //   and can be compared as integers. This is accomplished by using high-order
  //   bits to store a sort key.
  //
  // Keep track of the number of moves that we have considered at this node.
  //   After we finish searching moves at this node the move_list array will
  //   be organized in the following way:
  //
  //   m0, m1, ... , m_k-1, m_k, ... , m_N-1
  //
  //  where k = num_moves_tried, and N = num_of_moves
  //
  //  This will allow us to update the best_move_history table easily by
  //  scanning move_list from index 0 to k such that we update the table
  //  only for moves that we actually considered at this node.
  sortable_move_t move_list[MAX_NUM_MOVES];
  int num_of_moves = get_sortable_move_list(node, move_list, hash_table_move);
  int num_moves_tried = 0;

  // Start searching moves.
  for (int mv_index = 0; mv_index < num_of_moves; mv_index++) {
    // Incrementally sort the move list.
    sort_incremental(move_list, num_of_moves, mv_index);

    move_t mv = get_move(move_list[mv_index]);

    num_moves_tried++;
    (*node_count_serial)++;

    moveEvaluationResult result = evaluateMove(node, mv, killer_a, killer_b,
                                               SEARCH_PV,
                                               node_count_serial);

    if (result.type == MOVE_ILLEGAL || result.type == MOVE_IGNORE) {
      continue;
    }

    // A legal move is a move that's not KO, but when we are in quiescence
    // we only want to count moves that has a capture.
    if (result.type == MOVE_EVALUATED) {
      node->legal_move_count++;
    }

    // Check if we should abort due to time control.
    if (abortf) {
      return 0;
    }

    bool cutoff = search_process_score(node, mv, mv_index, &result, SEARCH_PV);
    if (cutoff) {
      break;
    }
  }

  if (node->quiescence == false) {
    update_best_move_history(&(node->position), node->best_move_index,
                             move_list, num_moves_tried);
  }

  tbassert(abs(node->best_score) != -INF, "best_score = %d\n",
           node->best_score);

  // Update the transposition table.
  //
  // Note: This function reads node->best_score, node->orig_alpha,
  //   node->position.key, node->depth, node->ply, node->beta,
  //   node->alpha, node->subpv
  update_transposition_table(node);

  return node->best_score;
}
Пример #23
0
score_t searchRoot(position_t *p, score_t alpha, score_t beta, int depth,
                   int ply, move_t *pv, uint64_t *node_count_serial,
                   FILE *OUT) {
  static int num_of_moves = 0;  // number of moves in list
  // hopefully, more than we will need
  static sortable_move_t move_list[MAX_NUM_MOVES];

  if (depth == 1) {
    // we are at depth 1; generate all possible moves
    num_of_moves = generate_all_opt(p, move_list, false);
    // shuffle the list of moves
    for (int i = 0; i < num_of_moves; i++) {
      int r = myrand() % num_of_moves;
      sortable_move_t tmp = move_list[i];
      move_list[i] = move_list[r];
      move_list[r] = tmp;
    }
  }

  searchNode rootNode;
  rootNode.parent = NULL;
  initialize_root_node(&rootNode, alpha, beta, depth, ply, p);


  assert(rootNode.best_score == alpha);  // initial conditions

  searchNode next_node;
  next_node.subpv[0] = 0;
  next_node.parent = &rootNode;

  score_t score;

  for (int mv_index = 0; mv_index < num_of_moves; mv_index++) {
    move_t mv = get_move(move_list[mv_index]);

    if (TRACE_MOVES) {
      print_move_info(mv, ply);
    }

    (*node_count_serial)++;

    // make the move.
    victims_t x = make_move(&(rootNode.position), &(next_node.position), mv);

    if (is_KO(x)) {
      continue;  // not a legal move
    }

    if (is_game_over(x, rootNode.pov, rootNode.ply)) {
      score = get_game_over_score(x, rootNode.pov, rootNode.ply);
      next_node.subpv[0] = 0;
      goto scored;
    }

    if (is_repeated(&(next_node.position), rootNode.ply)) {
      score = get_draw_score(&(next_node.position), rootNode.ply);
      next_node.subpv[0] = 0;
      goto scored;
    }

    if (mv_index == 0 || rootNode.depth == 1) {
      // We guess that the first move is the principle variation
      score = -searchPV(&next_node, rootNode.depth-1, node_count_serial);

      // Check if we should abort due to time control.
      if (abortf) {
        return 0;
      }
    } else {
      score = -scout_search(&next_node, rootNode.depth-1, node_count_serial);

      // Check if we should abort due to time control.
      if (abortf) {
        return 0;
      }

      // If its score exceeds the current best score,
      if (score > rootNode.alpha) {
        score = -searchPV(&next_node, rootNode.depth-1, node_count_serial);
        // Check if we should abort due to time control.
        if (abortf) {
          return 0;
        }
      }
    }

  scored:
    // only valid for the root node:
    tbassert((score > rootNode.best_score) == (score > rootNode.alpha),
             "score = %d, best = %d, alpha = %d\n", score, rootNode.best_score, rootNode.alpha);

    if (score > rootNode.best_score) {
      tbassert(score > rootNode.alpha, "score: %d, alpha: %d\n", score, rootNode.alpha);

      rootNode.best_score = score;
      pv[0] = mv;
      memcpy(pv+1, next_node.subpv, sizeof(move_t) * (MAX_PLY_IN_SEARCH - 1));
      pv[MAX_PLY_IN_SEARCH - 1] = 0;

      // Print out based on UCI (universal chess interface)
      double et = elapsed_time();
      char   pvbuf[MAX_PLY_IN_SEARCH * MAX_CHARS_IN_MOVE];
      getPV(pv, pvbuf, MAX_PLY_IN_SEARCH * MAX_CHARS_IN_MOVE);
      if (et < 0.00001) {
        et = 0.00001;  // hack so that we don't divide by 0
      }

      uint64_t nps = 1000 * *node_count_serial / et;
      fprintf(OUT, "info depth %d move_no %d time (microsec) %d nodes %" PRIu64
              " nps %" PRIu64 "\n",
              depth, mv_index + 1, (int) (et * 1000), *node_count_serial, nps);
      fprintf(OUT, "info score cp %d pv %s\n", score, pvbuf);

      // Slide this move to the front of the move list
      for (int j = mv_index; j > 0; j--) {
        move_list[j] = move_list[j - 1];
      }
      move_list[0] = mv;
    }

    // Normal alpha-beta logic: if the current score is better than what the
    // maximizer has been able to get so far, take that new value.  Likewise,
    // score >= beta is the beta cutoff condition
    if (score > rootNode.alpha) {
      rootNode.alpha = score;
    }
    if (score >= rootNode.beta) {
      tbassert(0, "score: %d, beta: %d\n", score, rootNode.beta);
      break;
    }
  }

  return rootNode.best_score;
}
Пример #24
0
main()
{
int x, y;			/* Coordinates of the player's move	*/
void init();			/* Initialises global variables.	*/
void get_move();		/* Gets a move from the player.		*/
void show_board();		/* Displays Othello Board.		*/
int make_move();		/* Make the move specified.		*/


init();				/* Initialise Othello.			*/


/* Main loop - repeats until end_othello takes a non-zero value
 */
while ( !end_othello )
	{
	/* Read in a move from the player.
	 *
	 * Note that the player's move, translated into coordinates in the
	 * Othello Board, is "returned" via pointers to (int)x and (int)y .
	 */
	get_move ( &x, &y );

	/* The first thing we check is whether or not the player has quit,
	 * skipped a go or restarted the game. x is set to -1 to indicate
	 * the latter two options.
	 */
	if ( !end_othello && x != -1 )
		{
		if ( make_move ( x, y ) )
			{
			/* Switch to next player if the move given was legal.
			 */
			if ( player == 0 )
				player = 1;
			else
				player = 0;

			/* Re-display the Othello Board.
			 */
			show_board();
			}
		else
			{
			/* Move was illegal, so try again.
			 */
			printf ( ": Illegal Move: Press a Key" );

			Bconin ( 2 );

			/* Back space over previous message, erase
			 * it and then backspace back again.
			 */
			printf ("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
			printf ("\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
			printf ( "                             " );
			printf ("\b\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
			printf ("\b\b\b\b\b\b\b\b\b\b\b\b\b\b");
			};
		};
	};


/* Handle error codes.
 */
printf ( "\n\n%s\nPress a Key\n", errors[end_othello - 1] );

Bconin ( 2 );


/* Free block of memory used by Othello Board if necessary.
 */
if ( board != NULL )
	free ( board );
};
Пример #25
0
int get_priority(trainer_s *trainer) {
	action_t action = trainer->action;
	return (is_move(action) ? get_move(trainer, action)->priority : 6); // if isn't move it is switch
}
Пример #26
0
/* --------------------------------------------------------------------------------------
	int alpha_beta(CHESS_STATE *node, int depth, int alpha, int beta)
    
    purpose: alpha-beta pruning evaluation of minimax algorithm
			 the algorithm always returns an absolute number
			 regardless of player's color.
			 + = good
			 - = bad

			beta represents previous player's best choice. Doesn't want it
			if alpha would worsen it.
   ---------------------------------------------------------------------------------------*/
int alpha_beta(CHESS_STATE *node, int current_depth, int fixed_depth_horizon, int alpha, int beta, ITERATIVE_DEEPENING_INFO *id_info)
{
	// leaf node test (include quiescence search)
	// note that we extend the current depth to go 1 PAST
	// the fixed depth horizon, to allow for check validation
	// at the leaf node. The quiescence search will automatically
	// cater for check validation
	if (current_depth>fixed_depth_horizon && !node->flg_is_noisy)
	{
		id_info[current_depth-1].moves_evaluated++;
		return node->board_value;
	}
	
	// otherwise, get opponents moves
	generate_moves(node);
	current_depth++;

	CHESS_STATE *p;
	CHESS_STATE *q;

	for (p = node->child_head; p != NULL; p = q) 
	{
		q = p->next;

		if (node->flg_is_white_move)
		{
			// maximiser
			if (alpha>=beta)
			{
				break;		// cutoff
			}
			int ab = alpha_beta(p, current_depth, fixed_depth_horizon, alpha, beta, id_info);
			if (ab > alpha)
			{
				alpha=ab;
				int d;
				
				if (current_depth==1)
					id_info[fixed_depth_horizon].best_move = get_move(p,0);
			}
		}
		else
		{
			// minimiser
			if (alpha>=beta)
			{
				break;		// cutoff
			}
			int ab = alpha_beta(p, current_depth, fixed_depth_horizon, alpha, beta, id_info);
			if (ab < beta)//
			{
				beta=ab;
				int d;
				if (current_depth==1)
					id_info[fixed_depth_horizon].best_move = get_move(p,0);
			}
		}
	}

	// legal moves (only required for depth 1)
	if (current_depth==1)
	{
		CHESS_STATE *child;

		int i=0;
		for (child=node->child_head; child!=NULL; child=child->next)
		{
			if (child->flg_is_illegal==0)
			{
				id_info[1].legal_moves[i] = get_move(child,0);
				i++;
			}
		}
		id_info[1].legal_move_count=i;
	}
	
	delete_nodes(node);
	
	if (node->flg_is_white_move)
	{
		// maximier
		return alpha;
	}
	else
	{
		return beta;
	}
}
Пример #27
0
move_s* curr_move() {
	return get_move(CURR_PLAYER, CURR_ACTION);
}
Пример #28
0
/**
 * Process a monster's turn
 *
 * 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 monster_turn(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;
	bool tracking = 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 (monster_turn_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 (!monster_turn_should_stagger(mon)) {
		if (!get_move(c, mon, &dir, &tracking)) 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];

		/* Tracking monsters have their best direction, don't change */
		if ((i > 0) && !stagger && !square_isview(c, oy, ox) && tracking) {
			break;
		}

		/* Check if we can move */
		if (!monster_turn_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) &&
			!monster_turn_glyph(c, mon, nx, ny))
			continue;

		/* Break a decoy if there is one */
		if (square_isdecoyed(c, ny, nx)) {
			/* Learn about if the monster attacks */
			if (monster_is_visible(mon))
				rf_on(lore->flags, RF_NEVER_BLOW);

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

			/* Wait a minute... */
			square_destroy_decoy(c, ny, nx);
			did_something = true;
			break;
		}

		/* The player is in the way. */
		if (square_isplayer(c, ny, nx)) {
			/* Learn about if the monster attacks */
			if (monster_is_visible(mon))
				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 (monster_is_visible(mon))
					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 = monster_turn_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);
			monster_turn_grab_objects(c, mon, m_name, nx, ny);
		}
	}

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

		/* Possible disturb */
		if (monster_is_visible(mon) && monster_is_in_view(mon) && 
			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 && monster_is_camouflaged(mon))
		become_aware(mon);
}
Пример #29
0
static score_t scout_search(searchNode *node, int depth,
                            uint64_t *node_count_serial, full_board_t* board) {


  // Initialize the search node.
  initialize_scout_node(node, depth);

  // check whether we should abort
  if (should_abort_check() || parallel_parent_aborted(node)) {
    return 0;
  }

  // Pre-evaluate this position.
  leafEvalResult pre_evaluation_result = evaluate_as_leaf(node, SEARCH_SCOUT, board);

  // If we decide to stop searching, return the pre-evaluation score.
  if (pre_evaluation_result.type == MOVE_EVALUATED) {
    return pre_evaluation_result.score;
  }

  // Populate some of the fields of this search node, using some
  //  of the information provided by the pre-evaluation.
  int hash_table_move = pre_evaluation_result.hash_table_move;
  node->best_score = pre_evaluation_result.score;
  node->quiescence = pre_evaluation_result.should_enter_quiescence;

  // Grab the killer-moves for later use.
  move_t killer_a = killer[KMT(node->ply, 0)];
  move_t killer_b = killer[KMT(node->ply, 1)];

  // Store the sorted move list on the stack.
  //   MAX_NUM_MOVES is all that we need.
  sortable_move_t move_list[MAX_NUM_MOVES];

  // Obtain the sorted move list.
  int num_of_moves = get_sortable_move_list(node, move_list, hash_table_move, board);
  int num_of_special_moves = move_list[num_of_moves];
  int num_of_nonzero_moves = move_list[num_of_moves + 1];
  if (num_of_special_moves == 0) {
    selectionSort(move_list, num_of_moves, 1);
    num_of_special_moves = 1;
  }
  int number_of_moves_evaluated = 0;

  bool generated_early_cutoff = false;

  for (int mv_index = 0; mv_index < num_of_special_moves; mv_index++) {
    int local_index = number_of_moves_evaluated++;
    move_t mv = get_move(move_list[local_index]);

    // increase node count
    REDUCER_VIEW(node_count_reducer)++;

    smallMoveEvaluationResult result = evaluateMove(node, mv, killer_a, killer_b,
                                               SEARCH_SCOUT,
                                               node_count_serial);

    if (result.type == MOVE_ILLEGAL || result.type == MOVE_IGNORE) {
      continue;
    }

    if (abortf || parallel_parent_aborted(node)) {
      return 0;
    }

    // A legal move is a move that's not KO, but when we are in quiescence
    // we only want to count moves that has a capture.
    if (result.type == MOVE_EVALUATED) {
      node->legal_move_count++;
    }

    // process the score. Note that this mutates fields in node.
    bool cutoff = search_process_score(node, mv, local_index, &result, SEARCH_SCOUT);

    if (cutoff) {
      generated_early_cutoff = true;
      break;
    }
  }

//  ABOVE IS YOUNG BROTHER'S WAIT CODE. IT SHOULD RUN IN SERIAL
//
//  BELOW IS PARALLELIZED SCOUT SEARCH. IT SHOULD RUN IN PARALLEL


  // if this happens, we generated an early cutoff in young brother's wait and can just skip to the end
  if (generated_early_cutoff)
    goto finish_scout_search;

  sort_incremental(move_list + num_of_special_moves, num_of_nonzero_moves - num_of_special_moves);

  // A simple mutex. See simple_mutex.h for implementation details.
  simple_mutex_t node_mutex;
  init_simple_mutex(&node_mutex);
  // TODO: see if changing this depth is better
  if (depth >= 2) {
    cilk_for (int mv_index = num_of_special_moves; mv_index < num_of_moves; mv_index++) {
      do {
        if (node->abort) continue;

        int local_index = __sync_fetch_and_add(&number_of_moves_evaluated, 1);

        move_t mv = get_move(move_list[local_index]);

        // increase node count
        REDUCER_VIEW(node_count_reducer)++;

        smallMoveEvaluationResult result = evaluateMove(node, mv, killer_a, killer_b,
                                                   SEARCH_SCOUT,
                                                   node_count_serial);

        // TODO: change this to break if we want to abort
        if (result.type == MOVE_ILLEGAL || result.type == MOVE_IGNORE) {
          continue;
        }

        if (abortf || parallel_parent_aborted(node)) {
          node->abort = true;
          continue;
        }

        // A legal move is a move that's not KO, but when we are in quiescence
        // we only want to count moves that has a capture.
        if (result.type == MOVE_EVALUATED) {
          __sync_fetch_and_add(&node->legal_move_count, 1);
        }

        bool cutoff = false;
        if (result.score > node->best_score) {
          simple_acquire(&node_mutex);
          // process the score. Note that this mutates fields in node.
          cutoff = search_process_score(node, mv, local_index, &result, SEARCH_SCOUT);
          simple_release(&node_mutex);
        }

        if (cutoff) {
          node->abort = true;
          continue;
        }
      } while (false);
    }
  } else {