Exemplo n.º 1
0
void collision()
{
	if (b1.isOnMap) {
		if (b1.x == tgt.x && b1.y == tgt.y) {
			map[tgt.y][tgt.x] = ' ';
			map[b1.y][b1.x] = ' ';
			b1.isOnMap = false;
			tgt.isOnMap = false;
			Score++;
			move_generator();
		}
	}
	if (b2.isOnMap) {
		if (b2.x == tgt.x && b2.y == tgt.y) {
			map[tgt.y][tgt.x] = ' ';
			map[b2.y][b2.x] = ' ';
			b2.isOnMap = false;
			tgt.isOnMap = false;
			Score++;
			move_generator();
		}
	}
}
Exemplo n.º 2
0
void update_tgt()
{
	int x = tgt.x;
	int y = tgt.y;
	if (y == 13) {
		map[y][x] = (x == 0 || x == 8) ? '|' : ' ';
		move_generator();
		tgt.isOnMap = false;
		Life--;
		return;
	}
	int nx, ny;
	ny = y + 1;
	if (x == 0 || x == 8) {
		map[y][x] = '|';
		tgt.dir *= -1;
	} else {
		map[y][x] = ' ';
	}
	nx = x + tgt.dir;
	map[ny][nx] = 'O';
	tgt.x = nx;
	tgt.y = ny;
}
Exemplo n.º 3
0
//=================================================================
// Negamax Function.
//=================================================================
static s32bit
negamax(s32bit depth_remaining, s32bit whos_turn_t, s32bit alpha, s32bit beta)
{
  Move   movelist[MAXMOVES], best;
  s32bit whos_turn = whos_turn_t & PLAYER_MASK;
  s32bit opponent  = whos_turn_t ^ PLAYER_MASK;
  s32bit value;
  s32bit init_alpha = alpha, init_beta = beta;
  u32bit start_nodes = g_num_nodes;
  Move   forcefirst;
  s32bit who_wins_value;

  s32bit stage = 0, state = 0, true_count, i = 0, num_moves = 1;

#ifdef DYNAMIC_POSITION_VALUES
  s32bit dyn_set;
#endif

  // increment a couple of stats
  g_num_nodes++;
#ifdef COLLECT_STATS
  stat_nodes[starting_depth - depth_remaining]++;
#endif

  // if no depth remaining stop search.
  if( depth_remaining <= 0 ){
    s32bit a = 0, b = 0;

    if( (a = does_next_player_win(whos_turn, 0)) > 0 ) {
      // current player wins.
      return 5000;
    }

    if( (b = does_who_just_moved_win(opponent, 0)) >= 0 ) {
      // opponent wins.
      return -5000;
    }
  
    return a - b;
  }
  

  //------------------------------------------
  // Can we determine a winner yet (simple check).
  //------------------------------------------

  // does current player win
  if(g_info_totals[whos_turn].safe > g_info_totals[opponent].real){
#ifdef COLLECT_STATS
    cut1++;
#endif
    return 5000;
  }
  
  // does opponent win
  if(g_info_totals[opponent].safe >= g_info_totals[whos_turn].real){
#ifdef COLLECT_STATS
    cut2++;
#endif
    return -5000;
  }


  //------------------------------------------
  // check transposition table
  //------------------------------------------

  forcefirst.array_index = -1;
  if(hashlookup(&value, &alpha, &beta, depth_remaining,
                &forcefirst, whos_turn))
    return value;
  // since we aren't using iter deep not interested in forcefirst.
  forcefirst.array_index = -1;
  

  //------------------------------------------
  // Can we determine a winner yet (look harder).
  //------------------------------------------

  // does current player win
  if( (who_wins_value = does_next_player_win(whos_turn, 0)) > 0 ) {

#ifdef DEBUG_NEGAMAX
    if(random() % 1000000 == -1){
      does_next_player_win(whos_turn, 1);
      print_board(whos_turn);
    }
#endif

#ifdef COLLECT_STATS
    cut3++;
#endif
    return 5000;
  }
    
  // does opponent win
  if( (who_wins_value = does_who_just_moved_win(opponent, 0)) >= 0 ) {

#ifdef DEBUG_NEGAMAX
    if(who_wins_value < 3){ // && random() % 500 == -1){
      does_who_just_moved_win(opponent, 1);
      //  print_board(opponent);
    }
#endif  

#ifdef COLLECT_STATS
    cut4++;
#endif
    return -5000;
  }

#if 0
  {
    s32bit num;
    num = move_generator_stage1(movelist, whos_turn);
    num = move_generator_stage2(movelist, num, whos_turn);
    if(move_generator(movelist, whos_turn) != num)
      fatal_error(1, "NOPE\n");
  }
#endif


  //------------------------------------------
  // Generate child nodes and examine them.
  //------------------------------------------

  // initialize a few variables. (some of them don't really need to be.)
  stage = state = true_count = i = 0;
  num_moves = 1;

#ifdef TWO_STAGE_GENERATION
  true_count = move_generator_stage1(movelist, whos_turn);
  if(true_count == 0){
    true_count = move_generator_stage2(movelist, 0, whos_turn);
    stage = 1;
    if(true_count == 0) fatal_error(1, "Should always have a move.\n");
  }
#else
  true_count = move_generator(movelist, whos_turn);
  stage = 1;
  if(true_count == 0)   fatal_error(1, "Should always have a move.\n");
#endif
  
  // score all the moves and move the best to the front.
  score_and_get_first(movelist, true_count, whos_turn, forcefirst);
  
  best = movelist[0];
  
  // need to sort moves and generate more moves in certain situations.
  while(state < 3){
    if(state == 0) {
      state = 1;
    } else if(state == 1){
      sort_moves(movelist, 1, true_count);
      num_moves = true_count;
      if(stage == 0) state = 2;
      else           state = 3;
    } else {
      num_moves = move_generator_stage2(movelist, num_moves, whos_turn);
      state = 3;
    }
    
    // Iterate through all the moves.
    for(; i < num_moves; i++){

      // A few statistics
      g_move_number[starting_depth - depth_remaining] = i;
#ifdef RECORD_MOVES
      g_move_player[starting_depth - depth_remaining] = whos_turn;
      g_move_position[starting_depth - depth_remaining] = movelist[i];
#endif

      // make move.
      g_empty_squares -= 2;
      toggle_move(movelist[i], whos_turn);
      toggle_hash_code
    (g_keyinfo[whos_turn][movelist[i].array_index][movelist[i].mask_index]);
#ifdef DYNAMIC_POSITION_VALUES
      dyn_set = set_move_value(movelist[i], whos_turn);
#endif
      
      // recurse.
      value = -negamax(depth_remaining-1,whos_turn^PLAYER_MASK,
                       -beta, -alpha);
      
      // undo move.
      g_empty_squares += 2;
      toggle_move(movelist[i], whos_turn);
      toggle_hash_code
    (g_keyinfo[whos_turn][movelist[i].array_index][movelist[i].mask_index]);
#ifdef DYNAMIC_POSITION_VALUES
      if(dyn_set != 0) unset_move_value(movelist[i], whos_turn);
#endif

#if 0
      if(starting_depth - depth_remaining == 8) {
        s32bit g;
        
        printf("goof:");
        
        for(g = 0; g < 8; g++){
          printf(" :%c:%d(%d,%d)", 
                 (g_move_player[g] == VERTICAL) ? 'V' : 'H',
                 g_move_number[g],
                 g_move_position[g].array_index - 1,
                 g_move_position[g].mask_index - 1);
        }
        printf("\n");
      }
#endif

      // If this is a cutoff, break.
      if(value >= beta){
        alpha = value;
        best  = movelist[i];
        
#ifdef COLLECT_STATS
        stat_cutoffs[starting_depth - depth_remaining]++;
        if(i < 5) stat_nth_try[starting_depth - depth_remaining][i]++;
        else      stat_nth_try[starting_depth - depth_remaining][5]++;
#endif
        break;
      }
      
      // If the current value is greater than alpha, increase alpha.
      if(value > alpha) {
        alpha = value;
        best  = movelist[i];
      }
    }

    // If we have broken out of previous FOR loop make sure we break out
    //   of this loop as well.
    if(value >= beta) break;
  }
  
  // save the position in the hashtable
  hashstore(alpha, init_alpha, init_beta, (g_num_nodes - start_nodes) >> 5,
            depth_remaining, best, whos_turn);
  
  return alpha;
}
Exemplo n.º 4
0
//=================================================================
// Search for move function. (Negamax Driver)
//=================================================================
extern s32bit
search_for_move(char dir, s32bit *row, s32bit *col, u64bit *nodes)
{
  s32bit  d, i, value = 0, num_moves;
  Move    movelist[MAXMOVES];
  s32bit  whos_turn;
  Move    forcefirst;
    
  // Set who's turn it is.
  if(toupper(dir) == 'V')      whos_turn = VERTICAL;
  else if(toupper(dir) == 'H') whos_turn = HORIZONTAL;
  else { fatal_error(1, "Invalid player.\n"); exit(1); }
  
  // initialize the number of empty squares.
  g_empty_squares = 0;
  for(i = 0; i < g_board_size[0]; i++)
    g_empty_squares += countbits32( (~g_board[0][i+1]) );
  
  // zero out all the statistics variables.
  init_stats();
  
  // Can we already determine a winner?
  {
    s32bit opponent = whos_turn ^ PLAYER_MASK;
    
    // stop search if game over.
    if(g_info_totals[whos_turn].safe > g_info_totals[opponent].real){
      // current player wins.
      *col = *row = -1;
      *nodes = 0;
      return 5000;
    }
    
    if(g_info_totals[opponent].safe >= g_info_totals[whos_turn].real){
      // opponent wins.
      *col = *row = -1;
      *nodes = 0;
      return -5000;
    }
  }
  
  // generate all possible moves for current player given current position.
  num_moves = move_generator(movelist, whos_turn);

  // This should never happen.
  if(num_moves == 0) fatal_error(1, "No moves");

  // should possibly sort the whole list instead of just get first.
  forcefirst.array_index = -1;
  score_and_get_first(movelist, num_moves, whos_turn, forcefirst);
  sort_moves(movelist, 1, num_moves);

  // Really this is for iterative deepening.
  for(d = 1; d < 50; d += 44){

    // Initialize alpha and beta.
    s32bit alpha = -5000, beta = 5000;

    // Re-initialize the statistics for each iteration.
    g_num_nodes = 0;
    init_stats();

    // set what the starting max depth is.
    starting_depth = d;
        
    // iterate through all the possible moves.
    for(i = 0; i < num_moves; i++){

#ifdef DYNAMIC_POSITION_VALUES
      init_move_value();
      set_move_value(movelist[i], whos_turn);
#else
      set_position_values();
#endif
      
      g_move_number[0] = i;
#ifdef RECORD_MOVES
      g_move_player[0] = whos_turn;
      g_move_position[0] = movelist[i];
#endif
      
      g_empty_squares -= 2;
      toggle_move(movelist[i], whos_turn);
      toggle_hash_code
    (g_keyinfo[whos_turn][movelist[i].array_index][movelist[i].mask_index]);
      check_hash_code_sanity();
      
      value = -negamax(d-1, whos_turn^PLAYER_MASK, -beta, -alpha);
      
#ifdef DYNAMIC_POSITION_VALUES
      unset_move_value(movelist[i], whos_turn);
#endif

      g_empty_squares += 2;
      toggle_move(movelist[i], whos_turn);
      toggle_hash_code
    (g_keyinfo[whos_turn][movelist[i].array_index][movelist[i].mask_index]);
      check_hash_code_sanity();

      printf("Move (%d,%d), value %d: %s.\n",
             movelist[i].array_index, movelist[i].mask_index,
             value, u64bit_to_string(g_num_nodes));
      printf("alpha %d, beta %d.\n", alpha, beta);

      movelist[i].info = value;

      if(value >= beta){
        alpha = value;
        break;
      }
      if(value > alpha) {
        alpha = value;
      }
    }

    if(value >= 5000){
      printf("Winner found: %d.\n", value);
      if(whos_turn == HORIZONTAL){
        *row = movelist[i].array_index;
        *col = movelist[i].mask_index;
      } else if(whos_turn == VERTICAL){
        *col = movelist[i].array_index;
        *row = movelist[i].mask_index;
      } else {
        fatal_error(1, "oops.");
      }
      
      *nodes = g_num_nodes;

      print_stats();
      
      return value;
    }

    // remove lossing moves from movelist.
    {
      s32bit rem = 0;
      for(i = 0; i < num_moves; i++){
        if(movelist[i].info <= -5000) rem++;
        else if(rem > 0) movelist[i-rem] = movelist[i];
      }
      num_moves -= rem;
      /*
      for(i = 0; i < num_moves; i++){
        printf("(%d,%d): %d.\n",
               movelist[i].array_index, movelist[i].mask_index,
               movelist[i].info);
      }
      */
    }

    print_stats();
    
    if(num_moves == 0){
      break;
    }
    
    // use a stable sort algorithm
    {
      Move swp;
      s32bit max, index, j;
      
      for(i=0; i<num_moves; i++) {
        max = movelist[i].info;
        index = i;
        
        for(j=i+1; j < num_moves; j++)
          if(movelist[j].info > max){
            max = movelist[j].info;
            index = j;
          }
    
        if(index != i){
          swp = movelist[index];
          //          printf("%d %d\n", index, i);
          for(j = index; j != i; j--){
            movelist[j] = movelist[j-1];
          }
          movelist[i] = swp;
        }
      }
    }
    
    printf("The value is %d at a depth of %d.\n", value, d);
    printf("Nodes: %u.\n", (u32bit)g_num_nodes);
  }

  *col = *row = -1;
  *nodes = g_num_nodes;

  return value;
}