예제 #1
0
파일: lion.c 프로젝트: abaheti95/OSlab
int check_availability(int curr_pit)
{
	int i;
	//printf("%s %d Checking Availability for %d\n",SELF,id,curr_pit);
	for(i = 0; i < N_PITS; i++)
	{
		//Mutex
		down(sem_mut,0);
		printf("%s %d requesting food from meat-pit %d\n",SELF,id,curr_pit);
		if(!occupied(sem_rival,curr_pit) && !occupied(sem_ranger,curr_pit) && semctl(sem_self,curr_pit,GETVAL,0) < semctl(sem_pit,curr_pit,GETVAL,0))
		{
			up(sem_mut,0);
			return curr_pit;
		}
		if(semctl(sem_pit,curr_pit,GETVAL,0) == 0)
			printf("Meat-pit %d empty\n",curr_pit);
		else	
			printf("%s %d denied access\n",SELF,id);
		up(sem_mut,0);
		// Change curr_pit
		curr_pit = curr_pit%N_PITS + 1;	
	}
	// No pit available
	return -1;
}
예제 #2
0
void DiplomacyRegion::display() {
    if (!occupied() && attacking_pieces.empty() && attacking_support.empty() && attacking_convoys.empty()
                    && defending_support.empty()) {
        return;
    }
    printf("Region: %s (%s)\n",names[0],names[1]);
    if (occupied()) {
        printf("\tThe region itself has %d occupiers.\n",occupiers.size());
        for (int i = 0; i < occupiers.size(); ++i) {
            occupiers[i]->display();
        }
        for (int i = 0; i < coasts.size(); ++i) {
            printf("------<coast>------\n");
            coasts[i]->display();
            printf("------</coast>-----\n");
        }
    }
    if (!attacking_pieces.empty()) {
        printf("\tThe region is under attack by %d pieces.\n",attacking_pieces.size());
        for (int i = 0; i < attacking_pieces.size(); ++i) {
            attacking_pieces[i]->display();
        }
    }
    if (!attacking_support.empty()) {
        printf("\tAttackers are being supported by %d pieces.\n",attacking_support.size());
        for (int i = 0; i < attacking_support.size(); ++i) {
            printf("\tThe piece: ");
            attacking_support[i]->supporter->display();
            printf("\tIs supporting: ");
            attacking_support[i]->supported->display();
        }
    }
}
예제 #3
0
void RingBuffer::readWithPad(double *data, unsigned int frames) {
    if (frames <= occupied()) {
        read(data, frames);
    }
    else {
        std::cout << "Underrun" << std::endl;
        // Not enough in the buffer so pad with zeros
        unsigned int padSize = frames - occupied();
        read(data, occupied());
        for (unsigned int i=0; i<padSize; i++) {
            data[frames - i - 1] = 0;
        }
    }
}
예제 #4
0
파일: lasutility.cpp 프로젝트: bsmaldon/lag
BOOL LASoccupancyGrid::write_asc_grid(const char* file_name) const
{
  FILE* file = fopen(file_name, "w");
  if (file == 0) return FALSE;
  fprintf(file, "ncols %d\012", max_x-min_x+1);
  fprintf(file, "nrows %d\012", max_y-min_y+1);
  fprintf(file, "xllcorner %f\012", grid_spacing*min_x);
  fprintf(file, "yllcorner %f\012", grid_spacing*min_y);
  fprintf(file, "cellsize %lf\012", grid_spacing);
  fprintf(file, "NODATA_value %d\012", 0);
  fprintf(file, "\012");
  I32 pos_x, pos_y;
  for (pos_y = min_y; pos_y <= max_y; pos_y++)
  {
    for (pos_x = min_x; pos_x <= max_x; pos_x++)
    {
      if (occupied(pos_x, pos_y))
      {
        fprintf(file, "1 ");
      }
      else
      {
        fprintf(file, "0 ");
      }
    }
    fprintf(file, "\012");
  }
  fclose(file);
  return TRUE;
}
예제 #5
0
파일: board.cpp 프로젝트: arcticmatt/CS2
/*
 * Returns true if a move is legal for the given side; false otherwise.
 */
bool Board::checkMove(Move *m, Side side) {
    // Passing is only legal if you have no moves.
    if (m == NULL) return !hasMoves(side);

    int X = m->getX();
    int Y = m->getY();

    // Make sure the square hasn't already been taken.
    if (occupied(X, Y)) return false;

    Side other = (side == BLACK) ? WHITE : BLACK;
    for (int dx = -1; dx <= 1; dx++) {
        for (int dy = -1; dy <= 1; dy++) {
            if (dy == 0 && dx == 0) continue;

            // Is there a capture in that direction?
            int x = X + dx;
            int y = Y + dy;
            if (onBoard(x, y) && get(other, x, y)) {
                do {
                    x += dx;
                    y += dy;
                } while (onBoard(x, y) && get(other, x, y));

                if (onBoard(x, y) && get(side, x, y)) return true;
            }
        }
    }
    return false;
}
예제 #6
0
파일: board.cpp 프로젝트: its-gucci/Othello
int Board::value(Side side) {
    int cost[8][8] = 
    {
        {99, -8, 8, 6, 6, 8, -8, 99},
        {-8, -24, -4, -3, -3, -4, -24, -8},
        {8, -4, 7, 4, 4, 7, -4, 8},
        {6, -3, 4, 0, 0, 4, -3, 6},
        {6, -3, 4, 0, 0, 4, -3, 6},
        {8, -4, 7, 4, 4, 7, -4, 8},
        {-8, -24, -4, -3, -3, -4, -24, -8},
        {99, -8, 8, 6, 6, 8, -8, 99}
    };
    int value = 0;
    for (int i = 0; i < 8; i++){
        for (int j = 0; j < 8; j++){
            if (occupied(i, j)){
                if (get(side, i, j)){
                    value = value + cost[i][j];
                }
                else {
                    value = value - cost[i][j];
                }
            }
        }
    }
    return value;
}
예제 #7
0
파일: board.c 프로젝트: hayamiz/blokusduo
bool validate_move_no_conflict(board_t * board, piece_info_t * move){
    uintptr_t i;

    if (!valid_coord(move->x, move->y)){
        return false;
    }

    piece_cell_t * cells;
    uintptr_t sz;
    cells = piece_info_points(move, &sz);

    for (i = 1;i < sz;i++){
        int8_t x,y;
        x = cells[i].x;
        y = cells[i].y;

        if (!valid_coord(x, y) || occupied(board, x, y)){
            free(cells);
            return false;
        }
    }
    free(cells);

    return true;
}
예제 #8
0
/* void Dstar::getSucc(state u,list<state> &s)
 * --------------------------
 * Returns a list of successor states for state u, since this is an
 * 8-way graph this list contains all of a cells neighbours. Unless
 * the cell is occupied in which case it has no successors.
 */
void Dstar::getSucc(state u,list<state> &s) {

  s.clear();
  u.k.first  = -1;
  u.k.second = -1;

  if (occupied(u)) return;

  u.x += 1;
  s.push_front(u);
  u.y += 1;
  s.push_front(u);
  u.x -= 1;
  s.push_front(u);
  u.x -= 1;
  s.push_front(u);
  u.y -= 1;
  s.push_front(u);
  u.y -= 1;
  s.push_front(u);
  u.x += 1;
  s.push_front(u);
  u.x += 1;
  s.push_front(u);

}
예제 #9
0
Shape Shape::rotateCW(int pivotX, int pivotY) const {
	Shape out { cols(), rows() };
	int dx, dy;
	int w = static_cast<int>(cols()), h = static_cast<int>(rows());
	int xmax = w - 1, ymax = h - 1;
	
	for (int sy = 0; sy < h; sy++)
		for (int sx = 0; sx < w; ++sx) {
			// px, py == 0, 0 means rotate around center
			if (pivotX == 0 && pivotY == 0) {
				dx = ymax - sy;
				dy = sx;
			}
			else {
				dx = ymax - sy - (ymax - (pivotX + pivotY));
				dy = sx - (pivotX - pivotY);
			}
			
			if (dx < 0 || dx > xmax || dy < 0 || dy > ymax)
				continue;
			
			auto tile = at(sx, sy);
			if (tile.occupied()) {
				tile.setRotation(tile.rotation() + 1);
				out.at(dx, dy) = tile;
			}
		}
	
	return out;
}
예제 #10
0
void set_color_scooch(burger* b, double dx, double dy, char* color, int direction) 
{
    int x = get_norm_x(b, dx);
    int y = get_norm_y(b, dy);
    if (occupied(b, x, y)) x += direction;
    b->color_matrix[y+(x*b->w)] = color;
}
예제 #11
0
void put_burger_scooch(burger* b, double dx, double dy, char c, int direction)
{
      int x = get_norm_x(b, dx);
      int y = get_norm_y(b, dy);
      if (occupied(b, x, y)) x += direction;
      update_frame(b,x,y);
      b->burger_matrix[y+(x*b->w)] = c;
}
예제 #12
0
bool RoombotBuildPlan::getConnector(size_t index, size_t connectorIndex) const
{
    int* xMods;
    int* zMods;
    int hxMods[NR_OF_CONNECTORS];
    int hyMods[NR_OF_CONNECTORS];
    int vxMods[NR_OF_CONNECTORS];
    int vyMods[NR_OF_CONNECTORS];
    
    vxMods[SOUTH_CONNECTOR] = 0;
    vxMods[SOUTH_EAST_CONNECTOR] = -1;
    vxMods[SOUTH_WEST_CONNECTOR] = 1;
    vxMods[NORTH_EAST_CONNECTOR] = -1;
    vxMods[NORTH_WEST_CONNECTOR] = 1;
    vxMods[NORTH_CONNECTOR] = 0;
    
    vyMods[SOUTH_CONNECTOR] = -1;
    vyMods[SOUTH_EAST_CONNECTOR] = 0;
    vyMods[SOUTH_WEST_CONNECTOR] = 0;
    vyMods[NORTH_EAST_CONNECTOR] = 1;
    vyMods[NORTH_WEST_CONNECTOR] = 1;
    vyMods[NORTH_CONNECTOR] = 2;
    
    hxMods[SOUTH_CONNECTOR] = -1;
    hxMods[SOUTH_EAST_CONNECTOR] = 0;
    hxMods[SOUTH_WEST_CONNECTOR] = 0;
    hxMods[NORTH_EAST_CONNECTOR] = 1;
    hxMods[NORTH_WEST_CONNECTOR] = 1;
    hxMods[NORTH_CONNECTOR] = 2;
    
    hyMods[SOUTH_CONNECTOR] = 0;
    hyMods[SOUTH_EAST_CONNECTOR] = 1;
    hyMods[SOUTH_WEST_CONNECTOR] = -1;
    hyMods[NORTH_EAST_CONNECTOR] = 1;
    hyMods[NORTH_WEST_CONNECTOR] = -1;
    hyMods[NORTH_CONNECTOR] = 0;
    
    if(positions[index].isHorizontal){
        xMods = hxMods;
        zMods = hyMods;
    } else {
        xMods = vxMods;
        zMods = vyMods;
    }
    
    if(connectorIndex == SOUTH_BOT_CONNECTOR ||
       connectorIndex == SOUTH_TOP_CONNECTOR ||
       connectorIndex == NORTH_BOT_CONNECTOR ||
       connectorIndex == NORTH_TOP_CONNECTOR)
    {
        return false;
    }
    
    int x =	positions[index].getX() + xMods[connectorIndex];
    int z = positions[index].getZ() + zMods[connectorIndex];
    
    return occupied(x, z);
}
예제 #13
0
파일: Map.cpp 프로젝트: Qata/Wibbly
bool Map::seize(unsigned tilePos)
{
	bool retVal = false;
	if (!occupied(tilePos) && at(tilePos) != mi_WallValue)
	{
		mba_Occupied[tilePos] = true;
		retVal = true;
	}
	return retVal;
}
예제 #14
0
bool can_castle(string input, unordered_map< string, string > *board, struct PlayerStatus &player_ps)
//if can successfully castle, updates board and returns true; returns false otherwise
{
	char player = piece_at(board, to_cart(player_ps.k_pos))[0];
	int row = (player == 'W')? 1:8;
	vector<int> king_start {5,row};
	vector<int> rook_start, rook_end, king_end;		
	if (input == "0-0"){ //king-side castling
		if (!player_ps.castle_k_side)
			return false;
		vector<int> rook_start {8,row};
		vector<int> rook_end {6,row};
		vector<int> king_end {7,row};
	}
	
	else{ //queen-side castling
		vector<int> queen_spot {4, row}; 
		if (!player_ps.castle_q_side || occupied(board, queen_spot))
			return false;
		
		vector<int> rook_start {1,row};
		vector<int> rook_end {4,row};
		vector<int> king_end {3,row};
	}
					
	if (!occupied(board,king_end) && !occupied(board,rook_end)){
		unordered_map<string,string> board2 = unordered_map<string,string>(*board); //make copy of board
		update_board(rook_start, rook_end, &board2);
		update_board(king_start, king_end, &board2);
		
		if (is_king_safe(&board2, player_ps)){
			update_board(rook_start, rook_end, board);
			update_board(king_start, king_end, board);
			
			player_ps.k_pos = to_str(king_end);
			player_ps.castle_k_side = false;
			player_ps.castle_q_side = false;
			return true;
		} 		
	}
	return false;

}
예제 #15
0
파일: board.c 프로젝트: hayamiz/blokusduo
bool validate_move_check_no_cross_edge(board_t * board
                                      , role_t role, int8_t x, int8_t y){
    piece_cell_t NG_cells[4] = {{x+1,y}, {x,y+1}, {x-1,y}, {x,y-1}};
    uintptr_t i;

    if (occupied(board, x, y)){
        return false;
    }
    
    for (i = 0;i < 4;i++){
        piece_cell_t * cell = &NG_cells[i];
        if (occupied(board, cell->x, cell->y)
            && role == occupied_by(board, cell->x, cell->y)){
            return false;
        }
    }

    return true;
}
예제 #16
0
void RingBuffer::read(double *data, unsigned int frames) {
    if (frames <= occupied()) {
        for (unsigned int i=0; i<frames; i++) {
            data[i] = _buffer[_readPos];
            std::cout << data[i] << std::endl;
            _readPos = _readPos + 1;
            if (_readPos == _size) {
                _readPos = 0;
            }
        }
        _occupied = _occupied - frames;
    }
}
예제 #17
0
파일: board.c 프로젝트: hayamiz/blokusduo
bool validate_move_check_cross_corner(board_t * board
                                      , role_t role, int8_t x, int8_t y){
    piece_cell_t required_cells[4] = {{x+1,y+1}, {x+1,y-1}, {x-1,y+1}, {x-1,y-1}};
    uintptr_t i;

    for (i = 0;i < 4;i++){
        piece_cell_t * cell = &required_cells[i];
        if (occupied(board, cell->x, cell->y)
            && role == occupied_by(board, cell->x, cell->y)){
            return true;
        }
    }

    return false;
}
예제 #18
0
파일: board.c 프로젝트: hayamiz/blokusduo
role_t occupied_by(board_t * board, int8_t x, int8_t y){
    if (!valid_coord(x,y)){
        return ROLE_NONE;
    }

    if (!occupied(board, x, y)){
        return ROLE_NONE;
    }

    uint32_t mask;
    mask = 1 << x;
    if (board->cellcolors[y] & mask){
        return ROLE_BLACK;
    }
    return ROLE_WHITE;
}
예제 #19
0
Permutation Permutation_interleave (Permutation me, long from, long to, long blocksize, long offset) {
	try {
		long n = Permutation_checkRange (me, &from, &to);
		long nblocks = n / blocksize;
		long nrest = n % blocksize;
		if (nrest != 0) Melder_throw ("There is not an integer number of blocks in the range.\n"
			                              "(The last block is only of size ", nrest, L" instead of ", blocksize, ").");
		if (offset >= blocksize) {
			Melder_throw (L"Offset must be smaller than blocksize.");
		}

		autoPermutation thee = Data_copy (me);

		if (nblocks == 1) {
			return thee.transfer();
		}

		autoNUMvector<long> occupied (1, blocksize);

		long posinblock = 1 - offset;
		for (long i = 1; i <= n; i++) {
			long index, rblock = (i - 1) % nblocks + 1;

			posinblock += offset;
			if (posinblock > blocksize) {
				posinblock -= blocksize;
			}

			if (i % nblocks == 1) {
				long count = blocksize;
				while (occupied[posinblock] == 1 && count > 0) {
					posinblock++; count--;
					if (posinblock > blocksize) {
						posinblock -= blocksize;
					}
				}
				occupied[posinblock] = 1;
			}
			index = from - 1 + (rblock - 1) * blocksize + posinblock;
			thy p[from - 1 + i] = my p[index];
		}
		return thee.transfer();
	} catch (MelderError) {
		Melder_throw (me, ": not interleaved.");
	}
}
예제 #20
0
/**
 * Counts score using the naive values for squares.  For Testing minimax
 */
int Board::getScoreNaive(Side side) 
{
    int score = 0;

    for(int i = 0; i < 8; i++) {
        for(int j = 0; j < 8; j++) {
            if(occupied(i, j)) {
                // if ours
                if(get(side, i, j)) {
                    score += naiveVal[i][j];
                }
                else {
                    score -= naiveVal[i][j];
                }
            }
        }
    }
    return score;
}
예제 #21
0
// Display the Square's contents.
void Square::display(ostream& outStream) const
{
    // Output whitespace.
    outStream << " ";

    // If the Square is occupied, then display the occupier of the Square.
    if (occupied())
    {
        // Display the occupier of the Square.
        occupiedBy().display(outStream);
    }
    // If the Square is not occupied, then display whitespace instead.
    else
    {
        // Display whitespace instead.
        outStream << "  ";
    }

    // Output whitespace followed by a bar to delineate the verticals on
    // the Square.
    outStream << " |";
}
예제 #22
0
/* void Dstar::getPred(state u,list<state> &s)
 * --------------------------
 * Returns a list of all the predecessor states for state u. Since
 * this is for an 8-way connected graph the list contails all the
 * neighbours for state u. Occupied neighbours are not added to the
 * list.
 */
void Dstar::getPred(state u,list<state> &s) {

  s.clear();
  u.k.first  = -1;
  u.k.second = -1;

  u.x += 1;
  if (!occupied(u)) s.push_front(u);
  u.y += 1;
  if (!occupied(u)) s.push_front(u);
  u.x -= 1;
  if (!occupied(u)) s.push_front(u);
  u.x -= 1;
  if (!occupied(u)) s.push_front(u);
  u.y -= 1;
  if (!occupied(u)) s.push_front(u);
  u.y -= 1;
  if (!occupied(u)) s.push_front(u);
  u.x += 1;
  if (!occupied(u)) s.push_front(u);
  u.x += 1;
  if (!occupied(u)) s.push_front(u);

}
예제 #23
0
        bool Board::move(Pieces_t::iterator source, Movements_t::const_iterator target)
        {
            if(source == pieces.end())
            {
                std::cerr << "source iterator of piece to move is invalid" << std::endl;
                return false;
            }
            if(target == trajectories.end() && target == capturings.end())
            {
                std::cerr << "target iterator of piece to move to is invalid" << std::endl;
                return false;
            }
            if(source != target->first)
            {
                std::cerr << "target iterator does not match source iterator, source{" << **source << "}, target {" << **(target->first) << "}" << std::endl;
                return false;
            }
            if(occupied(target->second))
            {
                std::cerr << "target iterator to move to is occupied:" << std::endl;
                for(auto &p : pieces)
                {
                    if(p->pos == target->second)
                    {
                        std::cerr << "\t" << *p << std::endl;
                    }
                }
                return false;
            }

            std::clog << "Moved piece at " << (*source)->pos << std::flush;
            (*source)->move(target->second);
            update(target->second);
            std::clog << " to " << target->second << std::endl;
            return true;
        }
예제 #24
0
/* bool Dstar::replan()
 * --------------------------
 * Updates the costs for all cells and computes the shortest path to
 * goal. Returns true if a path is found, false otherwise. The path is
 * computed by doing a greedy search over the cost+g values in each
 * cells. In order to get around the problem of the robot taking a
 * path that is near a 45 degree angle to goal we break ties based on
 *  the metric euclidean(state, goal) + euclidean(state,start). 
 */
bool Dstar::replan() {

  path.clear(); 
  
  int res = computeShortestPath();
  //  printf("res: %d ols: %d ohs: %d tk: [%f %f] sk: [%f %f] sgr: (%f,%f)\n",res,openList.size(),openHash.size(),openList.top().k.first,openList.top().k.second, s_start.k.first, s_start.k.second,getRHS(s_start),getG(s_start));

  if (res < 0) {
    //fprintf(stderr, "NO PATH TO GOAL\n");
    path.cost = INFINITY;
    return false;
  }
  list<state> n;
  list<state>::iterator i;

  state cur = s_start; 
  state prev = s_start;

  if (isinf(getG(s_start))) {
    //fprintf(stderr, "NO PATH TO GOAL\n");
    path.cost = INFINITY;
    return false;
  }
  
  // constructs the path
  while(cur != s_goal) {
    
    path.path.push_back(cur);
    path.cost += cost(prev,cur);
    getSucc(cur, n);

    if (n.empty()) {
      //fprintf(stderr, "NO PATH TO GOAL\n");
      path.cost = INFINITY;
      return false;
    }

    // choose the next node in the path by selecting the one with smallest 
    // g() + cost. Break ties by choosing the neighbour that is closest
    // to the line between start and goal (i.e. smallest sum of Euclidean 
    // distances to start and goal).
    double cmin = INFINITY;
    double tmin = INFINITY;
    state smin = cur;

    for (i=n.begin(); i!=n.end(); i++) {
  
      if (occupied(*i)) continue;
      double val  = cost(cur,*i);
      double val2 = trueDist(*i,s_goal) + trueDist(s_start,*i); // (Euclidean) cost to goal + cost to pred
      double val3 = getG(*i);
      val += val3;
      
      // tiebreak if curent neighbour is equal to current best
      // choose the neighbour that has the smallest tmin value
      if (!isinf(val) && near(val,cmin)) {
        if (val2 < tmin) { 
          tmin = val2;
          cmin = val;
          smin = *i;
        }
      }
      // if next neighbour (*i) is scrictly lower cost than the
      // current best, then set it to be the current best.
      else if (val < cmin) {
        tmin = val2;
        cmin = val;
        smin = *i;
      }
    } // end for loop

    n.clear();
    if( isinf(cmin) ) break;
    prev = cur;
    cur = smin;
  } // end while loop


  path.path.push_back(s_goal);
  path.cost += cost(prev,s_goal);
  return true;
}
예제 #25
0
파일: board.cpp 프로젝트: arcticmatt/CS2
bool Board::get(Side side, int x, int y) {
    return occupied(x, y) && (black[x + 8*y] == (side == BLACK));
}
예제 #26
0
void
fill_zoo (struct mkroom *sroom)
{
        struct monst *mon;
        int sx,sy,i;
        int sh, tx, ty, goldlim, type = sroom->rtype;
        int rmno = (sroom - rooms) + ROOMOFFSET;
        coord mm;


        sh = sroom->fdoor;
        switch(type) {
            case COURT:
                if(level.flags.is_maze_lev) {
                    for(tx = sroom->lx; tx <= sroom->hx; tx++)
                        for(ty = sroom->ly; ty <= sroom->hy; ty++)
                            if(IS_THRONE(levl[tx][ty].typ))
                                goto throne_placed;
                }
                i = 100;
                do {    /* don't place throne on top of stairs */
                        (void) somexy(sroom, &mm);
                        tx = mm.x; ty = mm.y;
                } while (occupied((signed char)tx, (signed char)ty) && --i > 0);
            throne_placed:
                /* TODO: try to ensure the enthroned monster is an M2_PRINCE */
                break;
            case BEEHIVE:
                tx = sroom->lx + (sroom->hx - sroom->lx + 1)/2;
                ty = sroom->ly + (sroom->hy - sroom->ly + 1)/2;
                if(sroom->irregular) {
                    /* center might not be valid, so put queen elsewhere */
                    if ((int) levl[tx][ty].roomno != rmno ||
                            levl[tx][ty].edge) {
                        (void) somexy(sroom, &mm);
                        tx = mm.x; ty = mm.y;
                    }
                }
                break;
            case ZOO:
            case LEPREHALL:
                goldlim = 500 * level_difficulty();
                break;
        }
        for(sx = sroom->lx; sx <= sroom->hx; sx++)
            for(sy = sroom->ly; sy <= sroom->hy; sy++) {
                if(sroom->irregular) {
                    if ((int) levl[sx][sy].roomno != rmno ||
                          levl[sx][sy].edge ||
                          (sroom->doorct &&
                           distmin(sx, sy, doors[sh].x, doors[sh].y) <= 1))
                        continue;
                } else if(!SPACE_POS(levl[sx][sy].typ) ||
                          (sroom->doorct &&
                           ((sx == sroom->lx && doors[sh].x == sx-1) ||
                            (sx == sroom->hx && doors[sh].x == sx+1) ||
                            (sy == sroom->ly && doors[sh].y == sy-1) ||
                            (sy == sroom->hy && doors[sh].y == sy+1))))
                    continue;
                /* don't place monster on explicitly placed throne */
                if(type == COURT && IS_THRONE(levl[sx][sy].typ))
                    continue;
                mon = makemon(
                    (type == COURT) ? courtmon() :
                    (type == BARRACKS) ? squadmon() :
                    (type == MORGUE) ? morguemon() :
                    (type == BEEHIVE) ?
                        (sx == tx && sy == ty ? &mons[PM_QUEEN_BEE] :
                         &mons[PM_KILLER_BEE]) :
                    (type == LEPREHALL) ? &mons[PM_LEPRECHAUN] :
                    (type == COCKNEST) ? &mons[PM_COCKATRICE] :
                    (type == ANTHOLE) ? antholemon() :
                    (struct permonst *) 0,
                   sx, sy, NO_MM_FLAGS);
                if(mon) {
                        mon->msleeping = 1;
                        if (type==COURT && mon->mpeaceful) {
                                mon->mpeaceful = 0;
                                set_malign(mon);
                        }
                }
                switch(type) {
                    case ZOO:
                    case LEPREHALL:
                        if(sroom->doorct)
                        {
                            int distval = dist2(sx,sy,doors[sh].x,doors[sh].y);
                            i = sq(distval);
                        }
                        else
                            i = goldlim;
                        if(i >= goldlim) i = 5*level_difficulty();
                        goldlim -= i;
                        (void) mkgold((long) rn1(i, 10), sx, sy);
                        break;
                    case MORGUE:
                        if(!rn2(5))
                            (void) mk_tt_object(CORPSE, sx, sy);
                        if(!rn2(10))    /* lots of treasure buried with dead */
                            (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,
                                             sx, sy, true, false);
                        if (!rn2(5))
                            make_grave(sx, sy, (char *)0);
                        break;
                    case BEEHIVE:
                        if(!rn2(3))
                            (void) mksobj_at(LUMP_OF_ROYAL_JELLY,
                                             sx, sy, true, false);
                        break;
                    case BARRACKS:
                        if(!rn2(20))    /* the payroll and some loot */
                            (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST,
                                             sx, sy, true, false);
                        break;
                    case COCKNEST:
                        if(!rn2(3)) {
                            struct obj *sobj = mk_tt_object(STATUE, sx, sy);

                            if (sobj) {
                                for (i = rn2(5); i; i--)
                                    (void) add_to_container(sobj,
                                                mkobj(RANDOM_CLASS, false));
                                sobj->owt = weight(sobj);
                            }
                        }
                        break;
                    case ANTHOLE:
                        if(!rn2(3))
                            (void) mkobj_at(FOOD_CLASS, sx, sy, false);
                        break;
                }
            }
        switch (type) {
              case COURT:
                {
                  struct obj *chest;
                  levl[tx][ty].typ = THRONE;
                  (void) somexy(sroom, &mm);
                  (void) mkgold((long) rn1(50 * level_difficulty(),10), mm.x, mm.y);
                  /* the royal coffers */
                  chest = mksobj_at(CHEST, mm.x, mm.y, true, false);
                  chest->spe = 2; /* so it can be found later */
                  level.flags.has_court = 1;
                  break;
                }
              case BARRACKS:
                  level.flags.has_barracks = 1;
                  break;
              case ZOO:
                  level.flags.has_zoo = 1;
                  break;
              case MORGUE:
                  level.flags.has_morgue = 1;
                  break;
              case SWAMP:
                  level.flags.has_swamp = 1;
                  break;
              case BEEHIVE:
                  level.flags.has_beehive = 1;
                  break;
        }
}
예제 #27
0
Path Map::findPath(int startX, int startY, int destX, int destY,
                   unsigned char walkmask, int maxCost)
{
    // Path to be built up (empty by default)
    Path path;

    // Declare open list, a list with open tiles sorted on F cost
    std::priority_queue<Location> openList;

    // Return when destination not walkable
    if (!getWalk(destX, destY, walkmask)) return path;

    // Reset starting tile's G cost to 0
    MetaTile *startTile = getMetaTile(startX, startY);
    startTile->Gcost = 0;

    // Add the start point to the open list
    openList.push(Location(startX, startY, startTile));

    bool foundPath = false;

    // Keep trying new open tiles until no more tiles to try or target found
    while (!openList.empty() && !foundPath)
    {
        // Take the location with the lowest F cost from the open list.
        Location curr = openList.top();
        openList.pop();

        // If the tile is already on the closed list, this means it has already
        // been processed with a shorter path to the start point (lower G cost)
        if (curr.tile->whichList == mOnClosedList)
        {
            continue;
        }

        // Put the current tile on the closed list
        curr.tile->whichList = mOnClosedList;

        // Check the adjacent tiles
        for (int dy = -1; dy <= 1; dy++)
        {
            for (int dx = -1; dx <= 1; dx++)
            {
                // Calculate location of tile to check
                const int x = curr.x + dx;
                const int y = curr.y + dy;

                // Skip if if we're checking the same tile we're leaving from,
                // or if the new location falls outside of the map boundaries
                if ((dx == 0 && dy == 0) || !contains(x, y))
                {
                    continue;
                }

                MetaTile *newTile = getMetaTile(x, y);

                // Skip if the tile is on the closed list or is not walkable
                // unless its the destination tile
                if (newTile->whichList == mOnClosedList ||
                    ((newTile->blockmask & walkmask)
                     && !(x == destX && y == destY)))
                {
                    continue;
                }

                // When taking a diagonal step, verify that we can skip the
                // corner.
                if (dx != 0 && dy != 0)
                {
                    MetaTile *t1 = getMetaTile(curr.x, curr.y + dy);
                    MetaTile *t2 = getMetaTile(curr.x + dx, curr.y);

                    if ((t1->blockmask | t2->blockmask) & BLOCKMASK_WALL)
                        continue;
                }

                // Calculate G cost for this route, ~sqrt(2) for moving diagonal
                int Gcost = curr.tile->Gcost +
                    (dx == 0 || dy == 0 ? basicCost : basicCost * 362 / 256);

                /* Demote an arbitrary direction to speed pathfinding by
                   adding a defect (TODO: change depending on the desired
                   visual effect, e.g. a cross-product defect toward
                   destination).
                   Important: as long as the total defect along any path is
                   less than the basicCost, the pathfinder will still find one
                   of the shortest paths! */
                if (dx == 0 || dy == 0)
                {
                    // Demote horizontal and vertical directions, so that two
                    // consecutive directions cannot have the same Fcost.
                    ++Gcost;
                }

                // It costs extra to walk through a being (needs to be enough
                // to make it more attractive to walk around).
                if (occupied(x, y))
                {
                    Gcost += 3 * basicCost;
                }

                // Skip if Gcost becomes too much
                // Warning: probably not entirely accurate
                if (Gcost > maxCost * basicCost)
                {
                    continue;
                }

                if (newTile->whichList != mOnOpenList)
                {
                    // Found a new tile (not on open nor on closed list)

                    /* Update Hcost of the new tile. The pathfinder does not
                       work reliably if the heuristic cost is higher than the
                       real cost. In particular, using Manhattan distance is
                       forbidden here. */
                    int dx = std::abs(x - destX), dy = std::abs(y - destY);
                    newTile->Hcost = std::abs(dx - dy) * basicCost +
                        std::min(dx, dy) * (basicCost * 362 / 256);

                    // Set the current tile as the parent of the new tile
                    newTile->parentX = curr.x;
                    newTile->parentY = curr.y;

                    // Update Gcost and Fcost of new tile
                    newTile->Gcost = Gcost;
                    newTile->Fcost = Gcost + newTile->Hcost;

                    if (x != destX || y != destY) {
                        // Add this tile to the open list
                        newTile->whichList = mOnOpenList;
                        openList.push(Location(x, y, newTile));
                    }
                    else {
                        // Target location was found
                        foundPath = true;
                    }
                }
                else if (Gcost < newTile->Gcost)
                {
                    // Found a shorter route.
                    // Update Gcost and Fcost of the new tile
                    newTile->Gcost = Gcost;
                    newTile->Fcost = Gcost + newTile->Hcost;

                    // Set the current tile as the parent of the new tile
                    newTile->parentX = curr.x;
                    newTile->parentY = curr.y;

                    // Add this tile to the open list (it's already
                    // there, but this instance has a lower F score)
                    openList.push(Location(x, y, newTile));
                }
            }
        }
    }

    // Two new values to indicate whether a tile is on the open or closed list,
    // this way we don't have to clear all the values between each pathfinding.
    mOnClosedList += 2;
    mOnOpenList += 2;

    // If a path has been found, iterate backwards using the parent locations
    // to extract it.
    if (foundPath)
    {
        int pathX = destX;
        int pathY = destY;

        while (pathX != startX || pathY != startY)
        {
            // Add the new path node to the start of the path list
            path.push_front(Position(pathX, pathY));

            // Find out the next parent
            MetaTile *tile = getMetaTile(pathX, pathY);
            pathX = tile->parentX;
            pathY = tile->parentY;
        }
    }

    return path;
}
예제 #28
0
파일: Map.cpp 프로젝트: Qata/Wibbly
bool Map::occupied(unsigned tileX, unsigned tileY)
{
	return occupied(tileY * width() + tileX);
}
예제 #29
0
void wsSolve(Array2D<char> const& wsArray,       //Wordsearch array to solve.
             StrLocMap&           matchMap)      //List of words and their locations
{
    /**
      * @brief Given the array (wsArray) and the list of words to find (domain of
      *        matchMap), wsSolve will fill the range of matchMap with the locations
      *        of the words to find. For instance, if matchMap contains
      *        (string1, locationData), wsSolve() fills in locationData
      *        with the location of the string. If the word is not found,
      *        locationData will remain unmodified.
      *
      *        The algorithm itself is quite complex. See wsSolveDoc.h for more
      *        information.
      *
      * @author MPW
      * @date 7/19/2008
      * @version 1
      *
      */

   typedef std::vector<Coord> CoordVec;

   //Declare the array of vectors of strings and set them all to empty vectors.
   Array2D<VecStr> occupied(wsArray.getWidth(), wsArray.getHeight());

   for (unsigned y = 0; y != wsArray.getHeight(); ++y)
   {
       for (unsigned x = 0; x != wsArray.getWidth(); ++x)
           occupied(x, y) = std::vector<std::string>();
   }

    //Find the list of letters to make a location list for, and for each letter,
    //pair the letter with a vector containing the coordinates of each occurrence
    //of that letter.

    //We go through the list, finding each letter to cache.
    std::map<char, CoordVec> cacheList;
    char prevChar = 0;
    char currentChar = 0;
    for (StrLocMap::iterator itr = matchMap.begin(); itr != matchMap.end();)
    {
        //currentChar is still from the previous loop! Hence, we set prevChar to
        //currentChar and update currentChar.
        prevChar = currentChar;
        currentChar = itr->first[0];

        //If the letter here is the same as the one before, it repeats (since
        //maps sort their elements in alphabetical order) (if this is
        //the first loop, this will never happen; prevChar will be nul, and no first
        //letter of a string can be nul; therefore, we don't count the first element
        //as appearing twice).
        if (currentChar == prevChar)
        {
            cacheList.insert(std::make_pair(currentChar, CoordVec()));

            //This trasverses the map until we get to a different character.
            while ((++itr != matchMap.end()) && (itr->first[0] == currentChar));

            //This is so the ++itr below does not execute.
            continue;
        }

        ++itr;
    }

    //Copy each of the strings into a multimap; this will sort the strings by
    //length.
    std::multimap<unsigned, std::string> strList;
    for (StrLocMap::iterator itr = matchMap.begin(); itr != matchMap.end(); ++itr)
        strList.insert(std::make_pair(itr->first.size(), itr->first));

    //Start the find.
    for (std::multimap<unsigned, std::string>::reverse_iterator itr = strList.rbegin();
         itr != strList.rend(); ++itr)
    {
        std::string& str = itr->second;
        bool isCached = !(cacheList.find(str[0]) == cacheList.end()); //Whether or not
                                                                      //the first letter
                                                                      //of the current
                                                                      //string is
                                                                      //cached.

        Coord startLocation(0, 0); //Location to start searching at; if the first
                                   //letter of the word's locations have been cached,
                                   //and none of the cached positions are the
                                   //location where str is found, startLocation is
                                   //set to the spot one after the last cached
                                   //position.
        if (isCached)
        {
            CoordVec& coordVec = cacheList[str[0]];
            if (coordVec.size() != 0)
            {
                //We assert here that the cached locations are in "ascending order";
                //see wsSolveDoc.h for more information.

                for (unsigned i = 0; i != coordVec.size(); ++i)
                {
                    //Contains the list of all possible directions the word can have
                    //at the given coordinates; see wsSolveDoc.h for more information.
                    std::vector<Direction> possibleDirList;
                    findWordAt(wsArray, str, coordVec[i], possibleDirList);

                    //Go through the vector, either until we find a valid direction
                    //the word can have, or until there are no possible directions
                    //the word can have left. (There's a chance possibleDir.empty() is
                    //already true, so in that case, just skip over that part.)
                    for (std::vector<Direction>::iterator itr2 = possibleDirList.begin();
                         itr2 != possibleDirList.end(); ++itr2)
                    {
                        if (!areAllOccupiedBySuperstring(occupied, str, coordVec[i], *itr2))
                        {
                            //You found the word!
                            matchMap[str] = LocationData(coordVec[i], *itr2);
                            setOccupied(occupied, str, coordVec[i], *itr2);

                            goto lblContinue;
                        }
                    }
                }
            }
        }

        //If the word was found in a cache, we skip over to lblContinue; however, we
        //would then be skipping over some variable declarations in the current
        //scope. This is banned by C++ syntax, so we wrap the following code in
        //another block.
        {
            Coord const endLocation(wsArray.getWidth(), wsArray.getHeight());
            Coord       location(startLocation);

            //Find the next occurrence of the character you're searching for.
            while ((location = searchForLetter(wsArray, str[0], location)) != endLocation)
            {
                //Cache this position (if relevant).
                if (isCached)
                    cacheList[str[0]].push_back(location);

                //Contains the list of all possible directions the word can have
                //at the given coordinates; see wsSolveDoc.h for more information.
                std::vector<Direction> possibleDirList;
                findWordAt(wsArray, str, location, possibleDirList);

                for (std::vector<Direction>::iterator itr2 = possibleDirList.begin();
                     itr2 != possibleDirList.end(); ++itr2)
                {
                    if (!areAllOccupiedBySuperstring(occupied, str, location, *itr2))
                    {
                        //You found the word!
                        matchMap[str] = LocationData(location, *itr2);
                        setOccupied(occupied, str, location, *itr2);

                        //You're done with this loop; you then enter the next loop
                        //(i.e., you search for the next string.)
                        goto lblContinue;
                    }
                }
                //Increase the location's position by 1; if it goes past the end of
                //the row, go down another row.
                if (location.pX < wsArray.getWidth())
                    ++location.pX;
                else
                {
                    if (location.pY < wsArray.getHeight())
                    {
                        //This code executes if you're on the last position on the
                        //last row; in that case, you're done.
                        ++location.pY;
                        location.pX = 0;
                    }
                    else
                        break;
                }
            }
        }

        lblContinue:
        continue;
    }
}
예제 #30
0
bool is_legal_move(vector<int> start, vector<int> end, const unordered_map< string, string > *board)
{
	int x1 = start[0], y1= start[1]; // 'start' coordinates
	int x2 = end[0], y2 = end[1]; // 'end' coordinates
	int devX = (x2 - x1 >= 0)? x2-x1: x1-x2; //absolute column deviation
	int devY = (y2 - y1 >= 0)? y2-y1: y1-y2; //absolute row deviation
		
	bool start_in_range = (x1 >= 1) && (x1 <= 8) && (y1 >= 1) && (y1 <= 8); // is valid starting point
	bool end_in_range = (x2 >= 1) && (x2 <= 8) && (y2 >= 1) && (y2 <= 8); // is valid ending point

	if (!(start_in_range && end_in_range)) // position(s) are off the board!
		return false;
	
	char colour = piece_at(board, start)[0];
	char piece = piece_at(board, start)[1];
	vector<int> intermediate;

	if (piece_at(board, end)[0] != colour){ //ending point is not already occupied by you
	
		if (piece == 'P'){ //PAWN
			int sign = (colour == 'W')? 1: -1;
			if( !occupied(board,end) && y2 == y1 + sign && devX == 0){ //standard jump
				return true;
			}
			else if (colour == 'W' && y1 == 2 && y2 == 4 && devX == 0){ //if white's first move, double jump allowed
				vector<int> intermediate {x1,3}; //intermediate position
				if (!occupied(board, end) && !occupied(board,intermediate))
					return true;
			}
			else if (colour == 'B' && y1 == 7 && y2 == 5 && devX == 0){ //if black's first move, double jump allowed
				vector<int> intermediate {x1,6}; //intermediate position
				if (!occupied(board, end) && !occupied(board,intermediate))
					return true;
			}
			else if (occupied(board,end) && y2 == y1 + sign  && devX == 1) //pawn makes a kill
				return true;
		}
		 
		else if (piece == 'R' || piece == 'Q'){ //ROOK/QUEEN
			int sign;			
			if (devY == 0) //no row deviation; moves along row
				sign = (x2 - x1) > 0? 1: -1;
				int j;
				for(j = 1; j < devX; ++j) {
					vector<int> intermediate {x1 + sign*j, y1};  //jth intermediate space
					if (occupied(board, intermediate))
						return false;
                }
				return true;
					
			if (devX == 0) //no column deviation; moves along column
				sign = (y2 - y1) > 0? 1: -1;
				int i;
				for(i = 1; i < devY; ++i) {
					vector<int> intermediate {x1,y1 + sign*i}; //jth intermediate space
					if (occupied(board, intermediate))
						return false;
                }
				return true;
			
		}
		else if (piece == 'N'){ //KNIGHT
			if ( (devY == 2 && devX == 1) || (devY == 1 && devX == 2))
				return true;
		}
		else if (piece == 'B' || piece == 'Q'){ //BISHOP/QUEEN
			if (devX == devY) {//absolute row deviation = absolute column deviation
				int y_sign = (y2 - y1) > 0? 1: -1;
				int x_sign = (x2 - x1) > 0? 1: -1;
				int k;
				
				for (k=1; k < devX; ++k){
					vector<int> intermediate {x1 + (x_sign)*k,y1 + (y_sign)*k}; //kth intermediate space
					if (occupied(board,intermediate))
						return false;
				}
				return true;
			}
		}			
		
		else if (piece == 'K'){ //KING
			if ( devX <= 1 && devY <= 1) //ensures that 'end' is only one move away from 'start'
				return true;
		}
		return false;
	}
	else
		return false;
}