public void FindHighGround(ref WindjermanGameState gs) { float ecartJoueurs = Unity.Mathematics.math.abs(gs.playerPosition1.y - gs.playerPosition2.y); if (playerID == 0) { if (ecartJoueurs > 4) { highGround = true; evenHight = false; } else { highGround = false; evenHight = true; } } else { if (ecartJoueurs > 4) { highGround = true; evenHight = false; } else { highGround = false; evenHight = true; } } }
public static long GetHashCodeJ2(ref WindjermanGameState gs) { var hash = 0L; hash += 10 + (long)math.round(math.clamp(math.distance(gs.playerPosition2.x, gs.frisbeePosition.x), 0, 8)); hash += 10 + (long)math.round(math.clamp(math.distance(gs.playerPosition2.y, gs.frisbeePosition.y), 0, 10)); return(hash); }
public static void UpdateFrisbee(ref WindjermanGameState gs) { if (gs.frisbeeFrozen) { gs.frisbeeSpeed = new Vector2(0, 0); return; } gs.frisbeePosition += gs.frisbeeSpeed; }
public float CalculerCurrentDistanceFromFrisbee(ref WindjermanGameState gs) { if (playerID == 0) { return(Vector2.Distance(gs.playerPosition1, gs.frisbeePosition)); } else { return(Vector2.Distance(gs.playerPosition2, gs.frisbeePosition)); } }
public static void Step(ref WindjermanGameState gs, int chosenPlayerAction1, int chosenPlayerAction2) { if (gs.isGameOver) { //throw new Exception("YOU SHOULD NOT TRY TO UPDATE GAME STATE WHEN GAME IS OVER !!!"); } UpdateFrisbee(ref gs); HandleAgentInputs1(ref gs, chosenPlayerAction1); HandleAgentInputs2(ref gs, chosenPlayerAction2); HandleCollisions(ref gs); }
public static int GetAvailableActions2int(ref WindjermanGameState gs) { if (gs.isFreeze2) { return(1); } if (gs.isStun2) { return(2); } return(0); }
public static NativeList <int> GetAvailableActions2(ref WindjermanGameState gs) { if (gs.isFreeze2) { return(AvailableActionsFrozen); } if (gs.isStun2) { return(AvailableActionsStun); } return(AvailableActionsFree); }
public static void HandleCollisions(ref WindjermanGameState gs) { var sqrDistance1 = (gs.frisbeePosition - gs.playerPosition1).sqrMagnitude; var sqrDistance2 = (gs.frisbeePosition - gs.playerPosition2).sqrMagnitude; //Collision with Players if ((sqrDistance1 <= Mathf.Pow(WindjermanGameState.frisbeeRadius + WindjermanGameState.playerRadius, 2))) { gs.frisbeePosition = new Vector2(gs.playerPosition1.x + 1.2f, gs.playerPosition1.y); gs.isFreeze1 = true; gs.frisbeeFrozen = true; } else if ((sqrDistance2 <= Mathf.Pow(WindjermanGameState.frisbeeRadius + WindjermanGameState.playerRadius, 2))) { gs.frisbeePosition = new Vector2(gs.playerPosition2.x - 1.2f, gs.playerPosition2.y); gs.isFreeze2 = true; gs.frisbeeFrozen = true; } //Rebound if (gs.frisbeePosition.y > 5 || gs.frisbeePosition.y < -5) { gs.frisbeeSpeed = new Vector2(gs.frisbeeSpeed.x, -gs.frisbeeSpeed.y); } //GOAL ! if (gs.frisbeePosition.x > 10) { gs.playerPosition1 = new Vector2(-5f, 0f); gs.playerPosition2 = new Vector2(5f, 0f); gs.frisbeeSpeed = new Vector2(0, 0); gs.frisbeePosition = new Vector2(5f, 0); gs.playerScore1 += 1; } if (gs.frisbeePosition.x < -10) { gs.playerPosition1 = new Vector2(-5f, 0f); gs.playerPosition2 = new Vector2(5f, 0f); gs.frisbeeSpeed = new Vector2(0, 0); gs.frisbeePosition = new Vector2(-5f, 0); gs.playerScore2 += 1; } }
public static void Init(ref WindjermanGameState gs) { gs.Timer = 0f; gs.isFreeze1 = true; gs.isFreeze2 = false; gs.frisbeeFrozen = false; gs.isStun1 = false; gs.isStun2 = false; gs.frisbeePosition = new Vector2(-5f, 0); gs.playerScore1 = 0; gs.playerScore2 = 0; gs.playerPosition1 = new Vector2(-5f, 0f); gs.playerPosition2 = new Vector2(5f, 0f); gs.isGameOver = false; gs.dureePartie = 120; }
public int Act(ref WindjermanGameState gs, NativeList <int> availableActions) { var job = new RandomRolloutJob { availableActions = availableActions, availableActionsFree = Rules.AvailableActionsFree, availableActionsStun = Rules.AvailableActionsStun, availableActionsFrozen = Rules.AvailableActionsFrozen, gs = gs, summedScores = new NativeArray <long>(availableActions.Length, Allocator.TempJob), rdmAgent = new RandomAgent { rdm = new Unity.Mathematics.Random((uint)Time.frameCount) }, Playerid = PlayerID }; var handle = job.Schedule(availableActions.Length, 1); handle.Complete(); var bestActionIndex = -1; var bestScore = long.MinValue; for (var i = 0; i < job.summedScores.Length; i++) { if (bestScore > job.summedScores[i]) { continue; } bestScore = job.summedScores[i]; bestActionIndex = i; } var chosenAction = availableActions[bestActionIndex]; job.summedScores.Dispose(); return(chosenAction); }
public static WindjermanGameState Clone(ref WindjermanGameState gs) { WindjermanGameState gsCopy = new WindjermanGameState(); gsCopy.frisbeeSpeed = gs.frisbeeSpeed; gsCopy.Timer = gs.Timer; gsCopy.playerPosition1 = gs.playerPosition1; gsCopy.playerPosition2 = gs.playerPosition2; gsCopy.frisbeePosition = gs.frisbeePosition; gsCopy.frisbeeFrozen = gs.frisbeeFrozen; gsCopy.isGameOver = gs.isGameOver; gsCopy.playerScore1 = gs.playerScore1; gsCopy.playerScore2 = gs.playerScore2; gsCopy.isFreeze1 = gs.isFreeze1; gsCopy.isFreeze2 = gs.isFreeze2; gsCopy.isStun1 = gs.isStun1; gsCopy.isStun2 = gs.isStun2; return(gsCopy); }
public int Act(ref WindjermanGameState gs, NativeList <int> availableActions) { if (PlayerID == 0) { if (Input.GetKey(KeyCode.Space) && !Input.GetKey(KeyCode.DownArrow) && !Input.GetKey(KeyCode.UpArrow)) { return(6); } if (Input.GetKey(KeyCode.Space) && Input.GetKey(KeyCode.DownArrow) && !Input.GetKey(KeyCode.UpArrow)) { return(5); } if (Input.GetKey(KeyCode.Space) && !Input.GetKey(KeyCode.DownArrow) && Input.GetKey(KeyCode.UpArrow)) { return(7); } if (Input.GetKey(KeyCode.DownArrow) && !Input.GetKey(KeyCode.RightArrow) && !Input.GetKey(KeyCode.LeftArrow) && !Input.GetKey(KeyCode.UpArrow)) { return(4); } if (Input.GetKey(KeyCode.UpArrow) && !Input.GetKey(KeyCode.RightArrow) && !Input.GetKey(KeyCode.LeftArrow) && !Input.GetKey(KeyCode.DownArrow)) { return(3); } if (Input.GetKey(KeyCode.LeftArrow) && !Input.GetKey(KeyCode.RightArrow) && !Input.GetKey(KeyCode.DownArrow) && !Input.GetKey(KeyCode.UpArrow)) { return(1); } if (Input.GetKey(KeyCode.RightArrow) && !Input.GetKey(KeyCode.DownArrow) && !Input.GetKey(KeyCode.LeftArrow) && !Input.GetKey(KeyCode.UpArrow)) { return(2); } } else if (PlayerID == 1) { if (Input.GetKey(KeyCode.LeftAlt) && !Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.Z)) { return(6); } if (Input.GetKey(KeyCode.LeftAlt) && Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.Z)) { return(5); } if (Input.GetKey(KeyCode.LeftAlt) && !Input.GetKey(KeyCode.S) && Input.GetKey(KeyCode.Z)) { return(7); } if (Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.D) && !Input.GetKey(KeyCode.Q) && !Input.GetKey(KeyCode.Z)) { return(4); } if (Input.GetKey(KeyCode.Z) && !Input.GetKey(KeyCode.D) && !Input.GetKey(KeyCode.Q) && !Input.GetKey(KeyCode.S)) { return(3); } if (Input.GetKey(KeyCode.Q) && !Input.GetKey(KeyCode.D) && !Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.Z)) { return(1); } if (Input.GetKey(KeyCode.D) && !Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.Q) && !Input.GetKey(KeyCode.Z)) { return(2); } } return(0); }
public int FindBestAction(ref NativeList <NodeAStar> listeNodes, ref WindjermanGameState gs, ref NativeList <int> availableActions) { float newDistancefromFrisbee = currentDistanceFromFrisbee; int indexClosestToFrisbee = 0; //si le joueur n'a pas le frisbee a l'instant T les bonnes action sont celles qui rapprochent le joueur de celui-ci if (playerID == 0) { if (!gs.isFreeze1 && gs.frisbeePosition.x < 0) { for (int i = 0; i < listeNodes.Length; i++) { //si l'action permet d'attraper le frisbee on la sélectionne if (listeNodes[i].hasFrisbee) { //listeNodes.Dispose(); return(i); } else { //si l'action réduit la distance entre le joueur et le frisbee, on conserve le résultat de cette action if (listeNodes[i].getDistanceFromFrisbee() < currentDistanceFromFrisbee) { indexClosestToFrisbee = i; currentDistanceFromFrisbee = listeNodes[i].getDistanceFromFrisbee(); } } } //listeNodes.Dispose(); return(indexClosestToFrisbee); } else { //si le joueur a le frisbee, les bonnes actions sont celles qui lancent le frisbee loin de l'autre joueur for (int i = 0; i < listeNodes.Length; i++) { //si le joueur a le highground, tirer tout droit est la meilleure option if (highGround) { //tirer tout droit est la meilleure option mais on ajoute une variation pour rendre le bot moins prédictible Unity.Mathematics.Random random = new Unity.Mathematics.Random((uint)UnityEngine.Random.Range(1, 100000)); float proba = random.NextFloat(0f, 3f); //si proba inférieure à 1, l'agent tire en diagonale if (proba < 1f) { bool probaDirection = random.NextBool(); if (probaDirection) { //tir en bas if (listeNodes[i].gsNode.frisbeePosition.y < listeNodes[i].gsNode.playerPosition1.y) { lastActionDone = availableActions[i]; listeNodes.Dispose(); return(i); } } else { //tir en haut if (listeNodes[i].gsNode.frisbeePosition.y > listeNodes[i].gsNode.playerPosition1.y) { lastActionDone = availableActions[i]; listeNodes.Dispose(); return(i); } } } else { //sinon il doit tirer tout droit if (listeNodes[i].gsNode.frisbeePosition.y == listeNodes[i].gsNode.playerPosition1.y) { lastActionDone = availableActions[i]; listeNodes.Dispose(); return(i); } } } else { //tirer en diagonale est la meilleure option mais on ajoute une variation pour rendre le bot moins prédictible Unity.Mathematics.Random random = new Unity.Mathematics.Random((uint)UnityEngine.Random.Range(1, 100000)); float proba = random.NextFloat(0f, 3f); //si proba inférieure à 1, l'agent tire tout droit if (proba < 1f) { //il doit tirer tout droit if (listeNodes[i].gsNode.frisbeePosition.y == listeNodes[i].gsNode.playerPosition1.y) { lastActionDone = availableActions[i]; return(availableActions[i]); } } else { //sinon il tire en diagonale avec une variation bool probaDirection = random.NextBool(); if (probaDirection) { //tir en bas if (listeNodes[i].gsNode.frisbeePosition.y < listeNodes[i].gsNode.playerPosition1.y) { lastActionDone = availableActions[i]; return(availableActions[i]); } } else { //tir en haut if (listeNodes[i].gsNode.frisbeePosition.y > listeNodes[i].gsNode.playerPosition1.y) { lastActionDone = availableActions[i]; return(availableActions[i]); } } } } } } } else { if (!gs.isFreeze2 && gs.frisbeePosition.x > 0) { for (int i = 0; i < listeNodes.Length; i++) { //si l'action permet d'attraper le frisbee on la sélectionne if (listeNodes[i].hasFrisbee) { //listeNodes.Dispose(); return(i); } else { //si l'action réduit la distance entre le joueur et le frisbee, on conserve le résultat de cette action if (listeNodes[i].getDistanceFromFrisbee() < currentDistanceFromFrisbee) { indexClosestToFrisbee = i; currentDistanceFromFrisbee = listeNodes[i].getDistanceFromFrisbee(); } } } //listeNodes.Dispose(); return(indexClosestToFrisbee); } else { //si le joueur a le frisbee, les bonnes actions sont celles qui lancent le frisbee loin de l'autre joueur for (int i = 0; i < listeNodes.Length; i++) { //si le joueur a le highground, tirer tout droit est la meilleure option if (highGround) { //tirer tout droit est la meilleure option mais on ajoute une variation pour rendre le bot moins prédictible Unity.Mathematics.Random random = new Unity.Mathematics.Random((uint)UnityEngine.Random.Range(1, 100000)); float proba = random.NextFloat(0f, 3f); //si proba inférieure à 1, l'agent tire en diagonale if (proba < 1f) { bool probaDirection = random.NextBool(); if (probaDirection) { //tir en bas if (listeNodes[i].gsNode.frisbeePosition.y < listeNodes[i].gsNode.playerPosition2.y) { lastActionDone = availableActions[i]; return(availableActions[i]); } } else { //tir en haut if (listeNodes[i].gsNode.frisbeePosition.y > listeNodes[i].gsNode.playerPosition2.y) { lastActionDone = availableActions[i]; return(availableActions[i]); } } } else { //sinon il doit tirer tout droit if (listeNodes[i].gsNode.frisbeePosition.y == listeNodes[i].gsNode.playerPosition2.y) { lastActionDone = availableActions[i]; return(availableActions[i]); } } } else { //tirer en diagonale est la meilleure option mais on ajoute une variation pour rendre le bot moins prédictible Unity.Mathematics.Random random = new Unity.Mathematics.Random((uint)UnityEngine.Random.Range(1, 100000)); float proba = random.NextFloat(0f, 3f); //si proba inférieure à 1, l'agent tire tout droit if (proba < 1f) { //il doit tirer tout droit if (listeNodes[i].gsNode.frisbeePosition.y == listeNodes[i].gsNode.playerPosition2.y) { lastActionDone = availableActions[i]; return(availableActions[i]); } } else { //sinon il tire en diagonale avec une variation bool probaDirection = random.NextBool(); if (probaDirection) { //tir en bas if (listeNodes[i].gsNode.frisbeePosition.y < listeNodes[i].gsNode.playerPosition2.y) { lastActionDone = availableActions[i]; return(availableActions[i]); } } else { //tir en haut if (listeNodes[i].gsNode.frisbeePosition.y > listeNodes[i].gsNode.playerPosition2.y) { lastActionDone = availableActions[i]; return(availableActions[i]); } } } } } } } return(0); }
public int Act(ref WindjermanGameState gs, NativeList <int> availableActions) { //déterminer la distance entre le joueur et le frisbee au moment T currentDistanceFromFrisbee = CalculerCurrentDistanceFromFrisbee(ref gs); FindHighGround(ref gs); //création de la liste des nodes var listeNodes = new NativeList <NodeAStar>(10, Allocator.Temp); //pour chaque action disponible for (int i = 0; i < availableActions.Length; i++) { //on crée un node NodeAStar n = new NodeAStar(); n.distanceFromFrisbee = 0; n.playerID = this.playerID; n.gsNode = Rules.Clone(ref gs); //on execute ladite action pour avoir le gamestate T+1 associé if (playerID == 0) { Rules.Step(ref n.gsNode, availableActions[i], 0); } else { Rules.Step(ref n.gsNode, 0, availableActions[i]); } //déterminer si le joueur a le frisbee à T+1 if (playerID == 0) { if (n.gsNode.isFreeze1) { n.hasFrisbee = true; } else { n.hasFrisbee = false; } } else { if (n.gsNode.isFreeze2) { n.hasFrisbee = true; } else { n.hasFrisbee = false; } } //déterminer la distance entre le joueur et le frisbee si celui-ci ne l'a pas en main à T+1 if (!n.hasFrisbee) { n.CalculerDistanceFromFrisbee(); } //si le joueur a le frisbee, déterminer sa situation par rapport à l'autre joueur else { n.FindHighGround(); } //ajouter le node à la liste listeNodes.Add(n); } //une fois les nodes créés, on détermine l'action à réaliser int action = FindBestAction(ref listeNodes, ref gs, ref availableActions); //listeNodes.Dispose(); return(action); }
public int Act(ref WindjermanGameState gs, NativeList <int> availableActions) { return(availableActions[rdm.NextInt(0, availableActions.Length)]); }
static void HandleAgentInputs1(ref WindjermanGameState gs, int chosenPlayerAction1) { var frisbeeVelocity = WindjermanGameState.frisbeeVelocity; switch (chosenPlayerAction1) { case 0: // DO NOTHING break; case 1: // LEFT { if (!gs.isFreeze1 && gs.playerPosition1.x > -9f) { gs.playerPosition1 += Vector2.left * WindjermanGameState.playerSpeed; } break; } case 2: // RIGHT { if (!gs.isFreeze1 && gs.playerPosition1.x < -2f) { gs.playerPosition1 += Vector2.right * WindjermanGameState.playerSpeed; } break; } case 3: // UP { if (!gs.isFreeze1) { if (!(gs.playerPosition1.y > 5)) { gs.playerPosition1 += Vector2.up * WindjermanGameState.playerSpeed; } } break; } case 4: // DOWN { if (!gs.isFreeze1) { if (!(gs.playerPosition1.y < -5)) { gs.playerPosition1 += Vector2.down * WindjermanGameState.playerSpeed; } } break; } case 5: //SHOOT DOWN { if (gs.isFreeze1) { // Debug.Log(gs.frisbeeFrozen); gs.frisbeeFrozen = false; gs.frisbeeSpeed = new Vector2(frisbeeVelocity, -frisbeeVelocity); gs.isFreeze1 = false; } break; } case 6: // SHOOT STRAIGHT { if (gs.isFreeze1) { gs.frisbeeFrozen = false; gs.frisbeeSpeed = new Vector2(frisbeeVelocity, 0f); gs.isFreeze1 = false; } break; } case 7: // SHOOT UP { if (gs.isFreeze1) { // Debug.Log(gs.frisbeeFrozen); gs.frisbeeFrozen = false; gs.frisbeeSpeed = new Vector2(frisbeeVelocity, frisbeeVelocity); gs.isFreeze1 = false; } break; } } }