Skip to content

JosedaMachine/IAV22-RaveRobayo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

IAV22-RaveRobayo

This repository is used for the final project of Artificial Intelligence signature.

Propuesta: Inteligencia Artificial que sea capaz de jugar en equipo a tactical shooters, para este proyecto nos centrariamos en reproducir los roles del tactical shooter multijugador Valorant, desarrollado por Riot Games, estos roles son :

-El controlador: encargado de colocar humos en el mapa para cancelar la visión del enemigo.

-El centinela: encargado de preveer flanqueos del enemigo y de contrarestarlos.

-El duelista: encargado de comprobar ángulos para su equipo y de entrar a las zonas de plante de la bomba.

-El iniciador: encargado de ayudar al duelista en su objetivo.

Para facilitar el trabajo, utilizaremos las habilidades (simplificadas, quitando físicas como la del lanzamiento de una flecha) de los siguientes personajes de Valorant. Controlador : Brimstone. Centinela : Cypher. Duelista : Jett. Iniciador: Sova.

El objetivo final de la práctica es que los personajes se comuniquen entre si, utilicen sus habilidades de forma coordinada y, si tuviesemos tiempo, implementar un machine learning en el que los personajes aprendan, donde se colcoan sus enemigos, como juegan sus compañeros, y que tácticas les son más y menos efectivas

Resumen

La práctica consiste en implementar una inteligencia artificial que sea capaz de trabajar en equipo junto con otras 3.

En este repositorio implementaremos la inteligencia artificial que hará las funciones de centinela, usando al personaje Cypher, del videojuego Valorant.

Valorant consiste de dos equipos, el atacante y el defensor, el equipo atacante debe plantar una bomba al lado de las cajas de radianita (un material valioso que permite generar enegergia rápidamente) para destruirla, mientras que el equipo atacante debe impedirlo. Nosotros nos centraremos en implementar la coordinación del ataque.


El entorno de la práctica será el sitio de B del mapa Bind de valorant, modelado en Blender y texturizado.

Rol en la partida

El centinela es aquel que debe ayudar a su equipo a preveer flanqueos del enemigo y contrarrestarlos. Cypher cuenta con dos cargas de cable trampa invisibles, que puede desplegar entre dos paredes cercanas. Si un enemigo atraviesa este cable, su presencia será revelada a todo el equipo de Cypher y no podrá disparar durante unos breves instantes.

Objetivo de la IA

El objetivo de esta IA es que ayude a sus compañeros a asegurar el terreno que han avanzado contrarrestando flanqueos del enemigo, y las mejores posiciones para sus cables.

Punto de partida

Utilizaremos una plantilla de shooter en primera persona para Unity para ahorrarnos el trabajo de implementar las mecánicas básicas de un shooter.

Pseudocódigo

function pathfindAStar(graph: Graph, start: Node, end: Node, heuristic: Heuristic ) -> Connection[]: # This structure is used to keep track of the # information we need for each node. class NodeRecord: node: Node connection: Connection costSoFar: float estimatedTotalCost: float

 # Initialize the record for the start node.
 startRecord = new NodeRecord()
 startRecord.node = start
 startRecord.connection = null
 startRecord.costSoFar = 0
 startRecord.estimatedTotalCost = heuristic.estimate(start)

 # Initialize the open and closed lists.
 open = new PathfindingList()

 open += startRecord
 closed = new PathfindingList()

 # Iterate through processing each node.
 while length(open) > 0:
	 # Find the smallest element in the open list (using the
	 # estimatedTotalCost).
	 current = open.smallestElement()

	 # If it is the goal node, then terminate.
	 if current.node == goal:
	 	break

	 # Otherwise get its outgoing connections.
	 connections = graph.getConnections(current)

	 # Loop through each connection in turn.
	 for connection in connections:
		 # Get the cost estimate for the end node.
		 endNode = connection.getToNode()
		 endNodeCost = current.costSoFar + connection.getCost()

	 # If the node is closed we may have to skip, or remove it
	 # from the closed list.
	 if closed.contains(endNode):
		 # Here we find the record in the closed list
		 # corresponding to the endNode.
		 endNodeRecord = closed.find(endNode)

	 # If we didn’t find a shorter route, skip.
	 if endNodeRecord.costSoFar <= endNodeCost:
	 	continue

		 # Otherwise remove it from the closed list.
		 closed -= endNodeRecord

		 # We can use the node’s old cost values to calculate
		 # its heuristic without calling the possibly expensive
		 # heuristic function.
		 endNodeHeuristic = endNodeRecord.estimatedTotalCost -
		 endNodeRecord.costSoFar

		 # Skip if the node is open and we’ve not found a better
		 # route.
	 else if open.contains(endNode):
		 # Here we find the record in the open list
		 # corresponding to the endNode.

	 	endNodeRecord = open.find(endNode)

	  # If our route is no better, then skip.
	  if endNodeRecord.costSoFar <= endNodeCost:
	  	continue

		  # Again, we can calculate its heuristic.
		  endNodeHeuristic = endNodeRecord.cost -
		  endNodeRecord.costSoFar

		  # Otherwise we know we’ve got an unvisited node, so make a
		  # record for it.
	  else:
		  endNodeRecord = new NodeRecord()
		  endNodeRecord.node = endNode

		  # We’ll need to calculate the heuristic value using
		  # the function, since we don’t have an existing record
		  # to use.
		  endNodeHeuristic = heuristic.estimate(endNode)

		  # We’re here if we need to update the node. Update the
		  # cost, estimate and connection.
		  endNodeRecord.cost = endNodeCost
		  endNodeRecord.connection = connection
		  endNodeRecord.estimatedTotalCost = endNodeCost +
		 endNodeHeuristic

	 # And add it to the open list.
	 if not open.contains(endNode):
		 open += endNodeRecord

	 # We’ve finished looking at the connections for the current
	 # node, so add it to the closed list and remove it from the
	 # open list.
	 open -= current
	 closed += current

 # We’re here if we’ve either found the goal, or if we’ve no more
 # nodes to search, find which.
 if current.node != goal:
 # We’ve run out of nodes without finding the goal, so there’s
 # no solution.
 return null

 else:
 # Compile the list of connections in the path.

 path = []

 # Work back along the path, accumulating connections.
 while current.node != start:
 path += current.connection
 current = current.connection.getFromNode()

 # Reverse the path, and return it.
 return reverse(path)

Utilizaremos una serie de puntos de influencia para saber que lugares son mejores para posicionar los cables trampa.

#Loading previous flanks flanks = previousFlanks;

#Loading height tripwireHeight = adequateHeight;

#When enemy steps on tripwire onEnemyTripped(){ if (col.getComponent()) { flanks.add(col.gameObject); sendMessage(enemyDetected); enemyStun(); } }

Utilizarempos un patron de envio de mensajes para conseguir que los personajes se comuniquen entre si.

#Sending messages send(msg type){ sendEnemyPosition(); // for example } #Recieving messages recieve(msg type){ if (enemyPositionType) { lookat(enemyPosition); } }

About

Repository for the Artificial Intelligence signature which is used for the final Project. 3º

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages