Strategická: Algoritmy pro C verzi
This commit is contained in:
		
							parent
							
								
									276c55531f
								
							
						
					
					
						commit
						f04db0468f
					
				
					 2 changed files with 93 additions and 3 deletions
				
			
		|  | @ -2,6 +2,8 @@ | |||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
| #include <queue> | ||||
| #include <set> | ||||
| #include <vector> | ||||
| #include <cassert> | ||||
| 
 | ||||
|  | @ -223,7 +225,93 @@ State* state; | |||
| 
 | ||||
| // Algoritmy
 | ||||
| 
 | ||||
| // main (zde doplňte kód)
 | ||||
| // otoč směr podle jiného otočení
 | ||||
| Direction combine_directions(Direction a, Direction b) | ||||
| { | ||||
| 	if (a == STAY || b == STAY) | ||||
| 	{ | ||||
| 		fprintf(stderr, "Nelze kombinovat se STAY."); | ||||
| 		exit(1); | ||||
| 	} | ||||
| 	return (Direction) ((a + b) % 4); | ||||
| } | ||||
| 
 | ||||
| // získej opačný směr
 | ||||
| Direction invert_direction(Direction a) | ||||
| { | ||||
| 	if (a == STAY) return STAY; | ||||
| 	return combine_directions(a, DOWN); | ||||
| } | ||||
| 
 | ||||
| // další políčko v daném směru
 | ||||
| Field* get_neighbour_field(Field* f, Direction direction) | ||||
| { | ||||
| 	int neighbour_i, neighbour_j; | ||||
| 	switch (direction) | ||||
| 	{ | ||||
| 		case UP: | ||||
| 			neighbour_i = f->i - 1; | ||||
| 			neighbour_j = f->j; | ||||
| 			break; | ||||
| 		case DOWN: | ||||
| 			neighbour_i = f->i + 1; | ||||
| 			neighbour_j = f->j; | ||||
| 			break; | ||||
| 		case LEFT: | ||||
| 			neighbour_i = f->i; | ||||
| 			neighbour_j = f->j - 1; | ||||
| 			break; | ||||
| 		case RIGHT: | ||||
| 			neighbour_i = f->i; | ||||
| 			neighbour_j = f->j + 1; | ||||
| 			break; | ||||
| 		default: | ||||
| 			neighbour_i = f->i; | ||||
| 			neighbour_j = f->j; | ||||
| 	} | ||||
| 
 | ||||
| 	// zajisti, aby souřadnice byly v rozsahu herní plochy
 | ||||
| 	neighbour_i %= state->world.size(); | ||||
| 	neighbour_j %= state->world[0].size(); | ||||
| 	return state->world[neighbour_i][neighbour_j]; | ||||
| } | ||||
| 
 | ||||
| // jestli daný tým může vstoupit na políčko
 | ||||
| bool is_field_accessible(Field* f, Team* t) | ||||
| { | ||||
| 	if (f->hill) return false; | ||||
| 	if (f->occupied_by_team != NULL && f->occupied_by_team != t) return false; | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
| // Najdi nejkratší cestu od vojáka k cílovému políčku.
 | ||||
| // Vrátí první krok, který má voják udělat.
 | ||||
| // Pokud žádná cesta neexistuje, vrátí STAY.
 | ||||
| Direction pathfind(Member* m, Field* goal) | ||||
| { | ||||
| 	std::set<Field*> explored; | ||||
| 	std::queue<Field*> queue; | ||||
| 	queue.push(goal); | ||||
| 	auto dirs = {UP, LEFT, DOWN, RIGHT}; | ||||
| 	while (!queue.empty()) | ||||
| 	{ | ||||
| 		auto field = queue.front(); | ||||
| 		queue.pop(); | ||||
| 		for (auto direction : dirs) | ||||
| 		{ | ||||
| 			auto neighbour = get_neighbour_field(field, direction); | ||||
| 			if (explored.find(neighbour) != explored.end()) continue; | ||||
| 			if (!is_field_accessible(neighbour, m->team)) continue; | ||||
|             // pokud jsme našli vojáka, vrátíme první krok
 | ||||
| 			if (neighbour == m->field) return invert_direction(direction); | ||||
| 			queue.push(neighbour); | ||||
| 			explored.insert(neighbour); | ||||
| 		} | ||||
| 	} | ||||
| 	return STAY; | ||||
| } | ||||
| 
 | ||||
| // Strategie
 | ||||
| 
 | ||||
| int main() | ||||
| { | ||||
|  | @ -231,7 +319,7 @@ int main() | |||
| 	scanf("%m[^\n]", &input_str); | ||||
| 	state = new State(input_str); | ||||
| 
 | ||||
| 	// TODO sem patří herní logika
 | ||||
| 	// TODO: zde doplňte svou herní strategii
 | ||||
| 	for(Member *m: state->my_team->members) | ||||
| 		m->action = UP; | ||||
| 
 | ||||
|  |  | |||
|  | @ -207,13 +207,15 @@ def pathfind(member: Member, goal: Field) -> Direction: | |||
|     # a také jednoduše získat první krok | ||||
|     explored: Set[Field] = set() | ||||
|     queue = collections.deque([goal]) | ||||
|     dirs = [Direction.UP, Direction.DOWN, Direction.LEFT, Direction.RIGHT] | ||||
|     while queue: | ||||
|         field = queue.popleft() | ||||
|         for direction in Direction: | ||||
|         for direction in dirs: | ||||
|             neighbour = field.get_neighbour_field(direction) | ||||
|             if (neighbour in explored or | ||||
|                 not neighbour.is_accessible(member.team)): | ||||
|                 continue | ||||
|             # pokud jsme našli vojáka, vrátíme první krok | ||||
|             if neighbour == member.field: | ||||
|                 return direction.invert() | ||||
|             queue.append(neighbour) | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue