// Update is called once per frame void move() { if (!automatic_play) { key_lock = false; foreach (KeyCode k in keys) { if (Input.GetKeyDown(k)) { if (!key_lock) { key_lock = true; StageController.instance.movecount += 1; grid_node target = sg.get_neighbour(current_node, (SquareGrid.orientation)arrow_to_orientation[k]); move_to_grid(sg, target); StageController.instance.Stage_switch(); } } } } else { int i = Random.Range(0, 4); grid_node target = sg.get_neighbour(current_node, SquareGrid.Four_dir[i]); move_to_grid(sg, target); StageController.instance.movecount += 1; StageController.instance.Stage_switch(); } }
void guess_and_move() { /*==========================Guess and move=========================== * According to the player's move, the robot will guess * which evador the player is targeting, and also move towards * that evador. * Right now I suggest players are targeting the Evador _e when: * - they keep shortening the manhattan distance between _e and themselves; * - if there are multiple, choose the closest one. * - I suppose evador are always running to exit,from the robot's propose. * =========================Guess and move==============================*/ if (player_target.Count == 0) { create_target_list(); } refresh_target_list(); evador_behave target_evador = Find_target(player_target); grid_node exit_node = sg.nodes.Find(x => x.state == SquareGrid.grid_stat.exit); grid_node target_grid = next_closest_to_target(target_evador.current_node, exit_node); target_grid.SendMessage("flash_me"); grid_node candidate = next_closest_to_target(current_node, target_grid); if (candidate != null) { move_to_grid(sg, candidate); } }
public SquareGrid Init_grid(int[,] int_grid) { /*====================================== * Initialize the grid with a integer matrix. * ========================================*/ SquareGrid sg = new SquareGrid(int_grid.GetLength(1), int_grid.GetLength(0)); for (int coord_x = 0; coord_x < sg.Width; coord_x++) { for (int coord_y = 0; coord_y < sg.Height; coord_y++) { V2Int pos = new V2Int(coord_x, coord_y); //instantiate new prefab GameObject grid = Instantiate(grid_prefab); grid.transform.position = get_pos(pos); grid.transform.SetParent(transform); //update grid_node according to input grid grid_node n = grid.GetComponent <grid_node>(); n.grid_position = pos; n.state = (SquareGrid.grid_stat)SquareGrid.int_to_stat[int_grid[coord_y, coord_x]]; n.set_color(get_color(n.state)); //set color grid.GetComponent <SpriteRenderer>().color = get_color(n.state); //update node list for the grid sg.nodes.Add(n); } } return(sg); }
int evaluate_evador(grid_node n) { //if uninitialized, initialize if (pursuers.Count == 0) { GameObject[] robots = GameObject.FindGameObjectsWithTag("robot"); foreach (GameObject r in robots) { pursuers.Add(r); } pursuers.Add(GameObject.FindGameObjectWithTag("Player")); } //initialized, evaluate according to them int result = 0; int[] threat_manhattan = new int[pursuers.Count]; for (int i = 0; i < pursuers.Count; i++) { V2Int opponent_pos = pursuers[i].GetComponent <moving>().current_node.grid_position; threat_manhattan[i] = Manhattan(opponent_pos, current_node.grid_position); } V2Int exit_pos = sg.nodes.Find(x => x.state == SquareGrid.grid_stat.exit).grid_position; return(Manhattan(exit_pos, current_node.grid_position) - Mathf.Min(threat_manhattan)); }
void block_exit() { //separately move towards exit grid_node exit = sg.nodes.Find(n => n.state == SquareGrid.grid_stat.exit); deploy_my_bots(exit); }
//is this grid walkable?[obstacles,out of boundary] public bool walkable(grid_node n) { bool x_in_range = (n.grid_position._x < this.Width) && (n.grid_position._x >= 0); bool y_in_range = (n.grid_position._y < this.Height) && (n.grid_position._y >= 0); bool not_obstacle = (n.state != grid_stat.obstacle); return(x_in_range && y_in_range && not_obstacle); }
protected bool valid_check(SquareGrid sg, grid_node target) { if (target == null) { return(false); } grid_node new_node = sg.nodes.Find(n => n.grid_position == target.grid_position); return(sg.walkable(new_node) && (!new_node.occupied)); }
void grid_initialize() //function that is called at run time to determine contents of grid { for (int i = 0; i < 25; i++) { for (int j = 0; j < 25; j++) { GRID[i, j] = new grid_node(i, j, false, TILE_TEXTURE.GRASS1_TILE_TEXTURE); } } }
List <grid_node> potential_movement(grid_node n) { List <grid_node> p = new List <grid_node>(); p.Add(n); foreach (grid_node nb in sg.my_neighbours(n)) { p.Add(nb); } return(p); }
int strategy_evaluate(grid_node nR1, grid_node nR2, area target) { area a1 = area_within_range(nR1); area a2 = area_within_range(nR2); area intersect1 = intersection(a1, target); area intersect2 = intersection(a2, target); int score = intersect1.pos_in_area.Count + intersect2.pos_in_area.Count; //better if target intersect with center in area overlay = intersection(intersect1, intersect2); score -= overlay.pos_in_area.Count; return(score); }
//All my neighbours. For MDP computation. public List <grid_node> my_neighbours(grid_node n) { List <grid_node> neighbour = new List <grid_node>(); foreach (orientation o in Four_dir) { grid_node nb = get_neighbour(n, o); if (nb != null) { neighbour.Add(nb); } } return(neighbour); }
grid_node astar(SquareGrid sg, grid_node startNode) { //* the Heuristic function that I am using is: //* Manhattan(n.grid_pos,exit) grid_node candidate = null; grid_node targetNode = sg.nodes.Find(n => n.state == SquareGrid.grid_stat.exit); //Is that right?? Heap <grid_node> openSet = new Heap <grid_node>(sg.Width * sg.Height); //Is that right?? //Heap<grid_node> openSet = new Heap<grid_node>(20); //HashSet<grid_node> closedSet = new HashSet<grid_node>(); List <grid_node> closedSet = new List <grid_node>(); openSet.Add(startNode); while (openSet.count > 0) { grid_node currentNode = openSet.remove_first(); closedSet.Add(currentNode); if (currentNode == targetNode) { //RetracePath(startNode,targetNode); candidate = closedSet[1]; //the next step?? break; } foreach (grid_node n in sg.my_neighbours(currentNode)) { if (!sg.walkable(n) || closedSet.Contains(n) || n.occupied) { continue; } int newMovementCostToNeighbour = currentNode.gCost + Manhattan(currentNode.grid_position, n.grid_position); if (newMovementCostToNeighbour < n.gCost || !openSet.Contains(n)) { n.gCost = newMovementCostToNeighbour; n.hCost = Manhattan(n.grid_position, targetNode.grid_position); n.parent = currentNode; if (!openSet.Contains(n)) { openSet.Add(n); } } } } candidate = closedSet.Count > 1?closedSet[1]:startNode; return(candidate); }
//what is the neighbour of this grid if I move at orientation o? public grid_node get_neighbour(grid_node n, orientation o) { V2Int nb_pos = n.grid_position + (V2Int)orient[o]; grid_node nb = nodes.Find(such_node => such_node.grid_position == nb_pos); if (nb != null) { if (walkable(nb)) { return(nb); } } return(null); }
//This is also bullshit. void Update() { if (Input.GetMouseButtonDown(0)) { Ray r = Camera.main.ScreenPointToRay(Input.mousePosition); RaycastHit hit; if (Physics.Raycast(r, out hit)) { grid_node n = hit.collider.gameObject.GetComponent <grid_node>(); List <grid_node> nbs = g.my_neighbours(n); IEnumerator c = flash_them(nbs); StartCoroutine(c); } } }
//heuristic use public List <grid_node> pure_neighbour(grid_node n) { List <grid_node> neighbour = new List <grid_node>(); foreach (orientation o in Four_dir) { V2Int nb_pos = n.grid_position + (V2Int)orient[o]; grid_node nb = nodes.Find(such_node => such_node.grid_position == nb_pos); if (nb != null && walkable(nb)) { neighbour.Add(nb); } } return(neighbour); }
grid_node next_closest_to_target(grid_node myself, grid_node target) { int min_dist = 0; grid_node candidate = null; foreach (grid_node n in sg.my_neighbours(myself)) { if (candidate == null) { candidate = n; min_dist = Manhattan(n.grid_position, target.grid_position); } else { candidate = Manhattan(n.grid_position, target.grid_position) < min_dist?n:candidate; } } return(candidate); }
//===============================A* Search========================= void IQ2_move() { grid_node candidate = null; /* set next move with A* pathfinding and avoid pursuers*/ candidate = evador_next(sg, current_node); if (candidate.state == SquareGrid.grid_stat.exit) { StageController.instance.score_evador += 1; //remove self from board move_to_grid(sg, candidate); current_node.occupied = false; explode(Color.green); DestroyImmediate(gameObject); } else { move_to_grid(sg, candidate); } }
//===============================Random move===================================== //===============================Simple Greedy Move========================= void IQ1_move() { /*this relatively clever movement is examine the whole grid * and use A* to move towards the exit as well as keep distance * with all the evadors; * * the Heuristic function that I am using is: * H(n)=Manhattan(n.grid_pos,exit)-Min(Manhattan(n.grid_pos,persuer)[]) */ int threat = 0; grid_node candidate = null; foreach (grid_node n in sg.my_neighbours(current_node)) { if (sg.walkable(n) && (!n.occupied)) { if (candidate == null) { candidate = n; threat = evaluate_evador(n); } else { candidate = evaluate_evador(n) > threat?n:candidate; } } } if (candidate != null) { move_to_grid(sg, candidate); if (candidate.state == SquareGrid.grid_stat.exit) { StageController.instance.score_evador += 1; //remove self from board current_node.occupied = false; explode(Color.green); DestroyImmediate(gameObject); } } }
//================================Visial Elements===================================== //===============================Random move===================================== void move(SquareGrid.orientation o) { //before move: chech whether go die grid_node target = sg.get_neighbour(current_node, o); move_to_grid(sg, target); if (target != null) { if (target.state == SquareGrid.grid_stat.exit) { StageController.instance.score_evador += 1; //remove self from board current_node.occupied = false; explode(Color.green); DestroyImmediate(gameObject); } } }
grid_node evador_next(SquareGrid sg, grid_node current_node) { grid_node candidate = astar(sg, current_node); Debug.Log(candidate == null); //if uninitialized, initialize if (pursuers.Count == 0) { GameObject[] robots = GameObject.FindGameObjectsWithTag("robot"); foreach (GameObject r in robots) { pursuers.Add(r); } pursuers.Add(GameObject.FindGameObjectWithTag("Player")); } //initialized, evaluate according to them /* do * { * foreach (grid_node n in dangerous_spot()) * if (sg.walkable(n) && (!n.not_ideal)) * { * if (candidate.grid_position == n.grid_position && candidate != current_node) * //If the possible next node of each pursuers overlaps the candidate, * //see the candidate node as an obstacle * candidate.not_ideal = true;//is that right?? * //recursive call, it will move since there are only three pursuers * candidate = astar(sg, current_node); * break; * } * * } while (candidate.not_ideal); * * foreach (grid_node n in sg.my_neighbours(current_node)) { * n.not_ideal = false; * }*/ return(candidate); }
protected void move_to_grid(SquareGrid sg, grid_node target) { if (valid_check(sg, target)) { grid_node pn = sg.nodes.Find(n => n.grid_position == target.grid_position); //new node has been occupied if (current_node != null) { current_node.occupied = false; } pn.occupied = true; transform.SetParent(pn.gameObject.transform); transform.localPosition = Vector3.zero + Vector3.back; //set old_node.occupied=fasle current_node = target; } else { Debug.LogWarning("This position is not available in the grid.\n" + " Check the positions."); } }
area area_within_range(grid_node x, int r = threat) { area target_area = new area(); target_area.pos_in_area = new List <grid_node>(); target_area.pos_in_area.Add(x); for (int i = 0; i < r; i++) { int num = target_area.pos_in_area.Count; for (int index = 0; index < num; index++) { foreach (grid_node nb in sg.pure_neighbour(target_area.pos_in_area[index])) { if (!target_area.pos_in_area.Contains(nb)) { target_area.pos_in_area.Add(nb); } } } } return(target_area); }
void move(SquareGrid.orientation o) { grid_node target = sg.get_neighbour(current_node, o); move_to_grid(sg, target); }
void move_received(grid_node next) { move_to_grid(sg, next); }
public void deploy_my_bots(grid_node target) { /*================this methods is only for 2 robot agents================== * within the threat, Robots will try to maximize the intersection area with target evador * which will have: * 2 list of potential movement * 2 iters iterating over the list * return indexes of movements * (this time:2*int) * ============================2-robot-agents==================================*/ area target_area = area_within_range(target);//default threat, can change to higher for test one-more step List <grid_node> potR0 = potential_movement(my_robots[0].current_node); List <grid_node> potR1 = potential_movement(my_robots[1].current_node); int max_score = 0; List <V2Int> good_strategy = new List <V2Int>(); good_strategy.Add(new V2Int(0, 0)); for (int index0 = 0; index0 < potR0.Count; index0++) { for (int index1 = 0; index1 < potR1.Count; index1++) { int current_score = strategy_evaluate(potR0[index0], potR1[index1], target_area); if (current_score > max_score) { max_score = current_score; good_strategy.Clear(); good_strategy.Add(new V2Int(index0, index1)); } else if (current_score == max_score) { good_strategy.Add(new V2Int(index0, index1)); } } } int strategy_num = good_strategy.Count; Debug.LogWarning("number of strategies:" + strategy_num); int min_sum = 20; int best = 0; //=========choose a best strategy according to sum up of scores================ for (int i = 0; i < strategy_num; i++) { grid_node next1 = potR0[good_strategy[i]._x]; grid_node next2 = potR1[good_strategy[i]._y]; int current_sum = Manhattan(next1.grid_position, target.grid_position) + Manhattan(next2.grid_position, target.grid_position); if (current_sum < min_sum) { best = i; min_sum = current_sum; } } Debug.LogWarning("I choose:" + best); my_robots[0].SendMessage("move_received", potR0[good_strategy[best]._x]); my_robots[1].SendMessage("move_received", potR1[good_strategy[best]._y]); StartCoroutine("stage_yield"); //==================2-robot-agents======================= }