void Board::advance_board(CongaBoard* new_conga_board)
{
  for (int x = 0; x < SQUARE_DIMENSION; ++x)
  {
    for (int y = 0; y < SQUARE_DIMENSION; ++y)
    {
      (*board)[x][y]->set_occupant((*new_conga_board)[x][y]->get_occupant());
      (*board)[x][y]->set_num_stones((*new_conga_board)[x][y]->get_num_stones());
    }
  }

  current_player = toggle_player(current_player);
}
// this evaluation function only cares about the moves the opponent can make,
// max score is 0 (win).
int Board::evaluate(Square::Player evaluate_for_player)
{
  int player_score = 0;
  Square::Player opponent = toggle_player(evaluate_for_player);
  for (int i = 0; i < SQUARE_DIMENSION; ++i)
  {
    for (int j = 0; j < SQUARE_DIMENSION; ++j)
    {
      if ((*board)[i][j]->get_occupant() == opponent)
      {
        player_score -= (find_available_directions(*(*board)[i][j])).size();
      }
    }
  }
  return player_score;
}
示例#3
0
bool Reversi::make_move(string move){
	//check size of move
	//cout << "Making move!\n";
	//cout << "size of move:" <<  sizeof(move) << endl;
	if(move.size() != 2)
		return false;
	//check if user has chosen side
	//cout << "Move sized correctly!\n";
	//cout << "current player:" << current_player << endl;
	if(current_player == 'n')
		return false;

	//split move into correct data types
	//cout << "Player has been set!\n";
	//cout << "Move string: " << move << endl;

	Position current_move;
	if(isalpha(move[0])) {
		current_move.column = get_number_of_letter(move[0]);
		current_move.row = move[1]-'0'-1;
	}
	else{
		current_move.row = get_number_of_letter(move[0]);
		current_move.column = move[1]-'0'-1;
	}
	//cout << "row: " << current_move.row << endl;
	//cout << "column: " << current_move.column << endl;

	// check if valid move
	bool possible_move_check = false;
	for(unsigned int i=0; i< available_moves.size(); i++)
		if(available_moves[i].row == current_move.row && available_moves[i].column == current_move.column)
			possible_move_check = true;

	if(!possible_move_check)
		return false;
	//cout << "Move is valid!\n";

	// save previous state
	// only need to support 10 undos (20 total saved states)
	if(previous_states.size() >= 20)
		previous_states.pop_back();
	
	previous_states.push_front({board, available_moves, white_score, black_score, current_player});
	previous_move = move;

	//check all directions
	//if valid in a direction flip all appropriate tiles
	vector<Position> all_positions;
	vector<Position> temp_positions;
	all_positions.push_back(current_move);
	int x_step = 0;
	int y_step = -1;
	temp_positions = get_tiles(current_move, x_step, y_step);		//check above
	for(unsigned int i=0; i<temp_positions.size(); i++)
		all_positions.push_back(temp_positions[i]);
	y_step = 1;
	temp_positions = get_tiles(current_move, x_step, y_step);		//check below
	for(unsigned int i=0; i<temp_positions.size(); i++)
		all_positions.push_back(temp_positions[i]);
	y_step = 0;
	x_step = 1;
	temp_positions = get_tiles(current_move, x_step, y_step);		//check right
	for(unsigned int i=0; i<temp_positions.size(); i++)
		all_positions.push_back(temp_positions[i]);
	x_step = -1;
	temp_positions = get_tiles(current_move, x_step, y_step);		//check left
	for(unsigned int i=0; i<temp_positions.size(); i++)
		all_positions.push_back(temp_positions[i]);
	y_step = -1;
	temp_positions = get_tiles(current_move, x_step, y_step);		//check top left
	for(unsigned int i=0; i<temp_positions.size(); i++)
		all_positions.push_back(temp_positions[i]);
	x_step = 1;
	temp_positions = get_tiles(current_move, x_step, y_step);		//check top right
	for(unsigned int i=0; i<temp_positions.size(); i++)
		all_positions.push_back(temp_positions[i]);
	y_step = 1;
	temp_positions = get_tiles(current_move, x_step, y_step);		//check bottom right
	for(unsigned int i=0; i<temp_positions.size(); i++)
		all_positions.push_back(temp_positions[i]);
	x_step = -1;
	temp_positions = get_tiles(current_move, x_step, y_step);		//check bottom left
	for(unsigned int i=0; i<temp_positions.size(); i++)
		all_positions.push_back(temp_positions[i]);
	for(unsigned int i=0; i<all_positions.size(); i++)
		board[all_positions[i].row][all_positions[i].column] = current_player;
	update_score();
	toggle_player();
	available_moves = get_available_moves();

	if(available_moves.size() == 0 && !(is_game_over())) {
		toggle_player();
		available_moves = get_available_moves();
	}
}
std::vector<Board::Direction>
Board::find_available_directions(Square& square)
{
  std::vector<Board::Direction> available_directions;
  Square::Player sq_occupant = square.get_occupant();

  if (sq_occupant == Square::NONE)
  {
    return available_directions;
  }

  Square::Player sq_opponent = toggle_player(sq_occupant);
  // check to see if movement on 8 directions is within boundaries first
  // then check the board to make sure at last one adjacent space is available
  if (square.get_y() + 1 < SQUARE_DIMENSION &&
    (*board)[square.get_x()][square.get_y() + 1]->get_occupant() != sq_opponent)
  {
    available_directions.push_back(Board::NORTH);
  }

  if (square.get_y() - 1 >= 0 &&
    (*board)[square.get_x()][square.get_y() - 1]->get_occupant() != sq_opponent)
  {
    available_directions.push_back(Board::SOUTH);
  }

  if (square.get_x() + 1 < SQUARE_DIMENSION &&
    (*board)[square.get_x() + 1][square.get_y()]->get_occupant() != sq_opponent)
  {
    available_directions.push_back(Board::EAST);
  }

  if (square.get_x() - 1 >= 0 &&
    (*board)[square.get_x() - 1][square.get_y()]->get_occupant() != sq_opponent)
  {
    available_directions.push_back(Board::WEST);
  }

  if (square.get_x() + 1 < SQUARE_DIMENSION && // check x + 1
    square.get_y() + 1 < SQUARE_DIMENSION && // check y + 1
      (*board)[square.get_x() + 1][square.get_y() + 1]->get_occupant()
        != sq_opponent) //check that diagonal is not blocked
  {
    available_directions.push_back(Board::NORTH_EAST);
  }

  if (square.get_x() + 1 < SQUARE_DIMENSION &&
    square.get_y() - 1 >= 0 &&
      (*board)[square.get_x() + 1][square.get_y() - 1]->get_occupant()
        != sq_opponent)
  {
    available_directions.push_back(Board::SOUTH_EAST);
  }

  if (square.get_x() - 1 >= 0 &&
    square.get_y() + 1 < SQUARE_DIMENSION &&
      (*board)[square.get_x() - 1][square.get_y() + 1]->get_occupant()
        != sq_opponent)
  {
    available_directions.push_back(Board::NORTH_WEST);
  }

  if (square.get_x() - 1 >= 0 &&
    square.get_y() - 1 >= 0 &&
      (*board)[square.get_x() - 1][square.get_y() - 1]->get_occupant()
        != sq_opponent)
  {
    available_directions.push_back(Board::SOUTH_WEST);
  }

  return available_directions;
}
Board* Board::travel(Square& square, Board::Direction direction)
{
  // Generate a new CongaBoard that is an exact copy of current
  Board::CongaBoard* new_board = new Board::CongaBoard();
  int x = square.get_x();
  int y = square.get_y();

  for (int x = 0; x < SQUARE_DIMENSION; ++x)
  {
    std::vector<Square*> column;

    for (int y = 0; y < SQUARE_DIMENSION; ++y)
    {
      Square* new_square = new Square(x, y);
      new_square->set_occupant((*board)[x][y]->get_occupant());
      new_square->set_num_stones((*board)[x][y]->get_num_stones());
      column.push_back(new_square);
    }

    new_board->push_back(column);
  }

  Square::Player sq_opponent = toggle_player(current_player);
  int delta_y = 0;
  int delta_x = 0;

  switch (direction)
  {
    case NORTH:
      delta_y = 1;
      break;

    case SOUTH:
      delta_y = -1;
      break;

    case EAST:
      delta_x = 1;
      break;

    case WEST:
      delta_x = -1;
      break;

    case NORTH_EAST:
      delta_y = 1;
      delta_x = 1;
      break;

    case NORTH_WEST:
      delta_y = 1;
      delta_x = -1;
      break;

    case SOUTH_EAST:
      delta_y = -1;
      delta_x = 1;
      break;

    case SOUTH_WEST:
      delta_y = -1;
      delta_x = -1;
      break;

    default:
      break;
  }

  for (int i = 1; i <= SQUARE_DIMENSION; ++i)
  {
    int sq_num_stones = (*new_board)[x][y]->get_num_stones();
    int y_i = y + i * delta_y;
    int x_i = x + i * delta_x;

    if (y_i >= SQUARE_DIMENSION ||
      y_i < 0 ||
      x_i >= SQUARE_DIMENSION ||
      x_i < 0 ||
      (*new_board)[x_i][y_i]->get_occupant() == sq_opponent)
    {
      if (i == 1)
      {
        // this should not happen
        printf("i == 1 in travel breaking\n");
        break;
      }

      // We have hit an opponent square or end of board so put all the
      // remaining stones on previous square
      (*new_board)[x_i - delta_x][y_i - delta_y]->set_num_stones((*new_board)[x_i - delta_x][y_i - delta_y]->get_num_stones() + sq_num_stones);
      sq_num_stones = 0;
    } else
    {
      if (sq_num_stones >= i)
      {
        sq_num_stones -= i;
        (*new_board)[x_i][y_i]->set_num_stones((*new_board)[x_i][y_i]->get_num_stones() + i);
      } else
      {
        (*new_board)[x_i][y_i]->set_num_stones((*new_board)[x_i][y_i]->get_num_stones() + sq_num_stones);
        sq_num_stones = 0;
      }

      (*new_board)[x_i][y_i]->set_occupant(current_player);
    }

    (*new_board)[x][y]->set_num_stones(sq_num_stones);

    if (sq_num_stones == 0)
    {
      (*new_board)[x][y]->set_occupant(Square::NONE);
      break;
    }
  }

  return new Board(new_board, sq_opponent);
}