<file_sep>using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;

public class Events : MonoBehaviour
{
    [SerializeField] GameObject[] objectList; // pauseMenu, player1, player2, vicMenuJ1, vicMenuJ2, menu, message, timer
    private Player lifePlayer;
    private PlayerController playerController;
    private BallMovement ballVel;
    private TextMeshProUGUI messageText;
    private TextMeshProUGUI timerText;
    private GameObject[] ball;
    public bool isPaused;
    public bool isInGame;
    private float timers;
    public static bool isAI;
    private int i = 0;

    public void Start() {
        BallMovement.isPlaying = false;
        BallMovement.isPlayingSimu = false;
        InvokeRepeating("EventXSeconds", 15.0f, 15.0f);
        Time.timeScale = 0f;
        isAI = false;
        messageText = objectList[6].GetComponent<TextMeshProUGUI>();
        timerText = objectList[7].GetComponent<TextMeshProUGUI>();
    }
    
    void Update()
    {
        ChangeGameMode();
        if(Input.GetKeyDown(KeyCode.Escape)) { //check if game is launched to use pause menu
            if(isPaused) {
                Pause(false, 1f);
            } else {
                if(isInGame) {
                    Pause(true, 0f);
                }
            }
        }

        if(isInGame) {
            timerText = objectList[7].GetComponent<TextMeshProUGUI>();
            timers += Time.deltaTime;
            int minutes = Mathf.FloorToInt(timers / 60F);
	        int seconds = Mathf.FloorToInt(timers % 60F);
	        int milliseconds = Mathf.FloorToInt((timers * 100F) % 100F);
	        timerText.SetText(minutes.ToString("00") + ":" + seconds.ToString("00") + ":" + milliseconds.ToString("00"));
        }
    }

    public void EventXSeconds() { //all possible events, +- ball velocity, +- players velocity & + life players
        if(isInGame == true) {
            i++;
            int chance = Random.Range(1, 100);
            if(chance <= 20) {
                messageText.SetText("MALUS : SPEEDBALL");
                ChangeBallVelocity(10f);
                Invoke("ResetBonusMalus", 10.0f);
            } else if(chance > 21 && chance <= 40) { // 20%
                messageText.SetText("BONUS : SLOWBALL");
                ChangeBallVelocity(1f);
                Invoke("ResetBonusMalus", 10.0f);
            } else if(chance > 41 && chance <= 60) {
                messageText.SetText("BONUS : SPEEDBOOST");
                ChangePlayerVelocity(objectList[1], 8f);
                ChangePlayerVelocity(objectList[2], 8f);
                Invoke("ResetBonusMalus", 10.0f);
            } else if(chance > 61 && chance <= 80) {
                messageText.SetText("MALUS : SLOWBOOST");
                ChangePlayerVelocity(objectList[1], 3f);
                ChangePlayerVelocity(objectList[2], 3f);
                Invoke("ResetBonusMalus", 10.0f);
            }  else if(chance > 96 && chance <= 100) { // 5% 
                messageText.SetText("BONUS : LIFE");
                ChangeLifePlayer(objectList[1], 1);
                ChangeLifePlayer(objectList[2], 1);
                Invoke("ResetBonusMalus", 10.0f);
            }
        }
    }

    private void ResetBonusMalus() {
        messageText.SetText("");
        ChangeBallVelocity(5f);
        ChangePlayerVelocity(objectList[1], 5.5f);
        ChangePlayerVelocity(objectList[2], 5.5f);
    }

    private void ChangeBallVelocity(float vel) {
        ball = GameObject.FindGameObjectsWithTag("ball");
        ballVel = ball[0].GetComponent<BallMovement>();
        ballVel.ballSpeed = vel;
    }

    private void ChangePlayerVelocity(GameObject obj, float vel) {
        playerController = obj.GetComponent<PlayerController>();
        playerController.playerSpeed = vel;
    }

    private void ChangeLifePlayer(GameObject obj, int health) {
        lifePlayer = obj.GetComponent<Player>();
        lifePlayer.life += health;
    }

    public void Pause(bool b, float t) {
        objectList[0].SetActive(b);
        Time.timeScale = t; 
        isPaused = b;
    }

    public void Restart() { //restart a party 
        objectList[1].transform.position = new Vector3(-5, 0, 0); //respawn
        objectList[2].transform.position = new Vector3(5, 0, 0);
        ChangeLifePlayer(objectList[1], 3); //reset lifes
        ChangeLifePlayer(objectList[2], 3);
        objectList[3].SetActive(false);
        objectList[4].SetActive(false);
        objectList[5].SetActive(false);
        messageText.SetText("");
        Time.timeScale = 1f;
        isInGame = true;
        timers = 0;
        i = 0;
        ball = GameObject.FindGameObjectsWithTag("ball");
        ball[0].transform.position = new Vector3(0, -3, 0);
        ballVel = ball[0].GetComponent<BallMovement>();
        ballVel.ballSpeed = 5f;
    }

    public void ChangeGameMode()
    {
        if (Input.GetKeyDown(KeyCode.F1))
        {
            if (isAI)
            {
                isAI = false;
            }
            else
            {
                isAI = true;
            }
        }
    }
}
<file_sep># Disc_Battle
Repository for the course Prog video games advanced
<file_sep>using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour
{
    public int life;
    [SerializeField] GameObject[] objectList; // victoryDeathMenu, Life1, Life2, Life3
    [SerializeField] Events ev;
    [SerializeField] PlayerController playerC;


    void Start() {
        this.life = 3;   
    }

    void Update() {
        if(life >= 3) {
            life = 3;
            objectList[1].SetActive(true);
            objectList[2].SetActive(true);
            objectList[3].SetActive(true);
        }
        if(life == 2) {
            objectList[1].SetActive(false);
        }
        if(life == 1) {
            objectList[2].SetActive(false);
        }
        if(life <= 0) {
            life = 0;
            objectList[3].SetActive(false);
            Time.timeScale = 0f;
            ev.isInGame = false;
            objectList[0].SetActive(true);
        }
    }

    void OnCollisionEnter(Collision other) {
        if (other.gameObject.CompareTag("ball"))  // if ball touch a player, life-- & respawn
        {
            life--;
            if(playerC.isPlayer) {
                this.transform.position = new Vector3(-5, 0, 0);
            } else {
                this.transform.position = new Vector3(5, 0, 0);
            }
        }
    }
}
<file_sep>using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BallEvents : MonoBehaviour
{
    //Ball value
    [SerializeField] private GameObject ball;

    public void SpawnBall() {   
        Instantiate(ball, ball.transform.position, Quaternion.identity);
    }
}
<file_sep>using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    //Smash values
    [SerializeField] private GameObject smashAreaPlayer;
    [SerializeField] private Transform smashPointPlayer;
    
    //Movement values
    private Vector3 lastDirectionIntent;
    private Vector3 lastDirectionIntent2;
    public float playerSpeed = 5.5f;
    public bool isPlayer;

    void Update() {
        GetMovement(isPlayer);
        SmashDaBall();
        lastDirectionIntent2.Normalize();
        lastDirectionIntent.Normalize();
    }

    private void FixedUpdate() {
        //Move Player1 or Player2
        if(isPlayer) {
            gameObject.transform.localPosition += lastDirectionIntent * (Time.deltaTime * playerSpeed);
        } else {
            gameObject.transform.localPosition += lastDirectionIntent2 * (Time.deltaTime * playerSpeed);
        }
    }

    private void SmashDaBall()
    {
        if (isPlayer)
        {
            if (Input.GetKeyDown(KeyCode.Space))
            {
                Smash();
            }   
        }
        else 
        {
            if (!Events.isAI)
            {
                if (Input.GetKeyDown(KeyCode.Return))
                {
                    Smash();
                }      
            }
        }
    }
    
    private void GetMovement(bool player) {
        if (player) {
            if (Input.GetKey(KeyCode.Z)) {
                WalkPlayer(player, Vector3.up);
            }
            if (Input.GetKey(KeyCode.Q)) {
                WalkPlayer(player, Vector3.left);
            }
            if (Input.GetKey(KeyCode.S)) {
                WalkPlayer(player, Vector3.down);
            }
            if (Input.GetKey(KeyCode.D)) {
                WalkPlayer(player, Vector3.right);
            }
            if (!Input.GetKey(KeyCode.Z) && !Input.GetKey(KeyCode.Q) && !Input.GetKey(KeyCode.S) && !Input.GetKey(KeyCode.D)) {
                lastDirectionIntent = Vector3.zero;
            }   
        } else {
            if (!Events.isAI)
            {
                if (Input.GetKey(KeyCode.UpArrow)) {
                    WalkPlayer(player, Vector3.up);
                }
                if (Input.GetKey(KeyCode.LeftArrow)) {
                    WalkPlayer(player, Vector3.left);
                }
                if (Input.GetKey(KeyCode.DownArrow)) {
                    WalkPlayer(player, Vector3.down);
                }
                if (Input.GetKey(KeyCode.RightArrow)) {
                    WalkPlayer(player, Vector3.right);
                }
            }
            if (!Input.GetKey(KeyCode.UpArrow) && !Input.GetKey(KeyCode.LeftArrow) && !Input.GetKey(KeyCode.DownArrow) && !Input.GetKey(KeyCode.RightArrow)) {
                lastDirectionIntent2 = Vector3.zero;
            }   
        }
    }

    public Vector3 WalkPlayer(bool player, Vector3 direction, float timeCall = 0)
    {
        if (player)
        {
            if (timeCall == 0)
            {
                lastDirectionIntent += direction * playerSpeed * Time.deltaTime;
            }
            else
            {
                for (int i = 0; i < timeCall; i++)
                {
                    lastDirectionIntent += direction * playerSpeed * Time.deltaTime;
                }
            }
        }
        else
        {
            if (timeCall == 0)
            {
                lastDirectionIntent2 += direction * playerSpeed * Time.deltaTime;
            }
            else
            {
                for (int i = 0; i < timeCall; i++)
                {
                    lastDirectionIntent2 += direction * playerSpeed * Time.deltaTime;
                }
            }
            
        }
        return gameObject.transform.position;
    }

    public void Smash()
    {
        //Instantiate prefab to make the ball bounce on it
        GameObject smash = Instantiate(smashAreaPlayer, smashPointPlayer.position, Quaternion.identity);
        //Destroy it soon after
        Destroy(smash, 0.3f);
    }

}
<file_sep>using UnityEngine;
using Random = UnityEngine.Random;

public class BallMovement : MonoBehaviour
{
    //Ball movement values
    public static Vector3 direction;
    public static float speedBall;
    public float ballSpeed = 5f;

    //Game State value (When the ball spawn the game start)
    public static bool isPlaying;
    public static bool isPlayingSimu;

    void Start()
    {
        //Determine a random direction for the ball to start
        direction = new Vector3(Random.Range(-1f, 1f), Random.Range(-1f, 1f), 0);
        isPlaying = true;
        isPlayingSimu = true;
    }

    // Update is called once per frame
    void Update()
    {
        speedBall = ballSpeed;
        transform.position += direction * (Time.deltaTime * speedBall);
    }

    public void OnCollisionEnter(Collision other)
    {
        Bounce(other);
    }

    public void Bounce(Collision collision)
    {
        //If the ball collide with a horizontal wall -> invert the y axis value
        if (collision.gameObject.CompareTag("horWall"))
        {
            direction.y *= -1;
        }
        //If the ball collide with a vertical wall -> invert the x axis value
        if (collision.gameObject.CompareTag("verWall"))
        {
            direction.x *= -1;
        }

        //Same behaviour as the vertical wall but speed up the ball
        if (collision.gameObject.CompareTag("smash"))
        {
            direction.x *= -1;
            ballSpeed += 1f;
        }
    }
}
<file_sep>using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Serialization;

public class MCTSIA : MonoBehaviour
{
    [SerializeField] private PlayerController p1;
    [SerializeField] private PlayerController p2;
    [SerializeField] private Collider[] wallsCollider;

    private GameObject ballPos;
    private Collider ballCollider;
    private Vector3 direction;
    private float speedBall;

    //Up, Down, Left, Right
    private Vector3[] actionsList = {
        new Vector3(0, 5, 0),
        new Vector3(0, -5, 0),
        new Vector3(-5, 0, 0),
        new Vector3(5, 0, 0),
    }; 

    private Vector3 p1PosSimuEnemy;
    private Vector3 p2PosSimu;
    private Vector3 BallPosSimu;
    // Start is called before the first frame update
    void Start()
    {
        InitActions();
    }

    // Update is called once per frame
    void Update()
    {
        if (BallMovement.isPlayingSimu)
        {
            ballPos = GameObject.FindGameObjectWithTag("ball");
            ballCollider = ballPos.GetComponent<Collider>();
            Simulate();
            Debug.Log(p1PosSimuEnemy);
        }
    }

    private int Simulate()
    {
        p1PosSimuEnemy += ChooseRandomAction();
        p2PosSimu += ChooseRandomAction();
        BallPosSimu = BallAction();
        Debug.Log(BallPosSimu);
        return 0;
    }

    //Initiate game values
    private void InitActions()
    {
        p1PosSimuEnemy = p1.transform.position;
        p2PosSimu = p2.transform.position;
        direction = new Vector3(Random.Range(-1f, 1f), Random.Range(-1f, 1f), 0);
        speedBall = 5f;
    }

    //Simulate the ball collision with a wall
    private Vector3 CheckBallCollision(Vector3 ballPos)
    {
        Vector3 newDirection = new Vector3(1, 1, 1);
        // In order walls : North, West, South, East
        if (ballPos.y + ballCollider.bounds.extents.y + 0.3 >= wallsCollider[0].bounds.min.y)
        {
            newDirection.y *= -1;
        }

        if (ballPos.x - ballCollider.bounds.extents.x <= wallsCollider[1].bounds.max.x)
        {
            newDirection.x *= -1;
        }
         
        if (ballPos.y - ballCollider.bounds.extents.y <= wallsCollider[2].bounds.max.y)
        {
            newDirection.y *= -1;
        }
         
        if (ballPos.x + ballCollider.bounds.extents.x  + 0.3 >= wallsCollider[3].bounds.min.x)
        {
            newDirection.x *= -1;
        }

        return newDirection;
    }
    
    //Simulate the ball action
    private Vector3 BallAction()
    {
        Vector3 positionBall = new Vector3();
        positionBall += CheckBallCollision(positionBall) * (Time.deltaTime * speedBall);
        return positionBall;
    }
    
    //TODO Add the smash to possible moves
    private Vector3 ChooseRandomAction()
    {
        Vector3 positionPlayer = new Vector3();
        var actionId = Random.Range(0, 4);
        //0 = Up, 1 = Down, 2 = Left, 3 = Right
        switch (actionId)
        {
            case 0:
                positionPlayer = actionsList[0];
                break;
            case 1:
                positionPlayer = actionsList[1];
                break;
            case 2:
                positionPlayer = actionsList[2];
                break;
            case 3:
                positionPlayer = actionsList[3];
                break;
        }

        return positionPlayer;
    }
}
<file_sep>using System;
using System.Collections;
using Microsoft.Win32.SafeHandles;
using UnityEngine;
using Random = UnityEngine.Random;

public class RandomIAInit : MonoBehaviour
{
    //Player to be controlled values
    [SerializeField] private PlayerController playerAI;

    //Random action values
    private int randomAction;
    private float actionCooldown;
    private float randomActionTime;
    private float smashCooldown;

    private void Update()
    {
        if (Events.isAI)
        {
            //Can do an action after the timer is 0
            actionCooldown -= Time.deltaTime;
            if (actionCooldown <= 0)
            {
                actionCooldown = 0.001f;
                RandomAction();   
            }   
        }
    }

    //Do a random action
    private void RandomAction()
    {
        randomAction = Random.Range(0, 5);
        randomActionTime = Random.Range(10, 30);
        switch (randomAction)
        {
            case 0:
                playerAI.WalkPlayer(false, Vector3.up, randomActionTime);
                break;
            case 1:
                playerAI.WalkPlayer(false, Vector3.down, randomActionTime);
                break;
            case 2:
                playerAI.WalkPlayer(false, Vector3.left, randomActionTime);
                break;
            case 3:
                playerAI.WalkPlayer(false, Vector3.right, randomActionTime);
                break;
            case 4:
                smashCooldown -= Time.deltaTime;
                if (smashCooldown <= 0)
                {
                    smashCooldown = 0.2f;
                    playerAI.Smash();   
                }
                break;
        }
    }
}
