using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace EvilSquashConsole
{
    public class Tiles
    {
        public bool special = false;
        public int toWhere = 0;
    }
    
    
    public class Player
    {
        
        public bool isRealPerson = false;
        public int CurPos = 0;
        public int prevPos = 0;
        public int prevprevPos = 0;
        public string name;
        public double AvgRoll = 0;
        public int numTurns = 0;
        public int num6s = 0;
        public int TurnsSinceBouce;
        public bool JustBounced = false;
        public string preference;
    }
    
    class Program
    {
        
        static bool gameEnd = false;
        static Tiles[] MainTiles  = new Tiles[64];
        static Player[] Players = new Player[4];
        public static int numPlayers = 0;
        static int numAIPlayers = 0;
        static int turn = 0;
        static int roll = 0;
        static bool ThreeSixesRolled = false;
        static string SquashOrBounce;
        static bool rodneyTaken;
        static bool freddyTaken;
        static bool eddieTaken;
        static Random AIGenerator = new Random();
        static int AIPicked = 0;
        static bool AIDone = false;
        static void SquashOrBounceMeth()
        {
            for (int i = 0; i < Players.Length; i++)
            {
                if (turn == i)
                {
                }
                else
                {
                    if (Players[turn].CurPos == Players[i].CurPos)
                    {
                        bool ValidationLoop = false;
                        Console.WriteLine("You have landed on " + Players[i].name);
                        Console.WriteLine("Type S to evil squash or B to bounce...");
                        switch (Players[turn].preference)
                        {
                            case "b":
                                Console.WriteLine("b");
                                SquashOrBounce = "b";
                                break;
                            case "s" :
                                Console.WriteLine("s");
                                SquashOrBounce = "s";
                                break;
                            case "r" :
                                
                                switch (AIGenerator.Next(1, 3))
                                {
                                    case 1:
                                        Console.WriteLine("s");
                                        SquashOrBounce = "s";
                                        break;
                                    case 2:
                                        Console.WriteLine("b");
                                        SquashOrBounce = "b";
                                        break;
                                }
                                break;
                            default :
                                // you are currently doing preferences for AI.
                                break;
                        }
                        if (Players[turn].isRealPerson == true)
                            SquashOrBounce = Console.ReadLine();
                        if (Players[turn].JustBounced == true)
                            SquashOrBounce = "s";
                        
                        do
                        {
                            if (Players[turn].JustBounced == true)
                                SquashOrBounce = "s";
                            
                            switch (SquashOrBounce.ToLower())
                            {
                                case "s":
                                    Console.WriteLine("You have squashed " + Players[i].name + " back to square " + Players[turn].prevPos);
                                    if (Players[turn].JustBounced == true)
                                    {
                                        Players[i].CurPos = Players[turn].prevprevPos;
                                        Players[turn].JustBounced = false;
                                        ValidationLoop = true;
                                    }
                                    else
                                    {
                                        Players[i].CurPos = Players[turn].prevPos;
                                        ValidationLoop = true;
                                    }
                                    break;
                                case "b":
                                    Console.WriteLine("You have decided to bounce press any key to roll again...");
                                    Console.ReadLine();
                                    roll = DiceRoll();
                                    Console.WriteLine("You have rolled a: " + roll);
                                    if (roll == 6)
                                        Players[turn].num6s++;
                                    else
                                        Players[turn].num6s = 0;
                                    if (Players[turn].num6s == 3)
                                    {
                                        Console.WriteLine("You have rolled three sixes in a row, you go back to the start!");
                                        Players[turn].CurPos = 0;
                                        Players[turn].num6s = 0;
                                        ThreeSixesRolled = true;
                                    }
                                    Players[turn].prevprevPos = Players[turn].prevPos;
                                    Players[turn].prevPos = Players[turn].CurPos;
                                    Players[turn].CurPos += roll;
                                    Players[turn].JustBounced = true;
                                    ValidationLoop = true;
                                    break;
                                default:
                                    Console.WriteLine("Type S to evil squash or B to bounce...");
                                    SquashOrBounce = Console.ReadLine();
                                    break;
                            }
                        } while (!ValidationLoop);
                        
                        ValidationLoop = true;
                        if (Players[turn].JustBounced == true)
                        {
                            SquashOrBounceMeth();
                        }
                    }
                }
            }
        }
        
        static void Main(string[] args)
        {
#region Initialisation
            Console.BackgroundColor = ConsoleColor.White;
            Console.Clear();
            Console.ForegroundColor = ConsoleColor.Black;
            for (int i = 0; i < MainTiles.Length; i++)
            {
                MainTiles[i] = new Tiles();
                MainTiles[i].special = false;
            }
            // initialising the tiles that have arrows on
            MainTiles[1].special = true;
            MainTiles[1].toWhere = 16;
            MainTiles[9].special = true;
            MainTiles[9].toWhere = 27;
            MainTiles[12].special = true;
            MainTiles[12].toWhere = 3;
            MainTiles[17].special = true;
            MainTiles[17].toWhere = 30;
            MainTiles[28].special = true;
            MainTiles[28].toWhere = 21;
            MainTiles[38].special = true;
            MainTiles[38].toWhere = 41;
            MainTiles[45].special = true;
            MainTiles[45].toWhere = 50;
            MainTiles[46].special = true;
            MainTiles[46].toWhere = 33;
            MainTiles[54].special = true;
            MainTiles[54].toWhere = 28;
            MainTiles[60].special = true;
            MainTiles[60].toWhere = 54;
            for (int i = 0; i < Players.Length; i++)
            {
                Players[i] = new Player();
            }
            numPlayerGetter();
            numAIPlayers = 4 - numPlayers;
            for (int i = 1; i < numPlayers + 1; i++)
            {
                Console.WriteLine();
                Console.WriteLine("Enter Player" + i + "'s name");
                Players[i - 1].name = Console.ReadLine();
                Players[i - 1].isRealPerson = true;
            }
            if (numAIPlayers > 0)
            {
                for (int i = 1; i < numAIPlayers + 1; i++)
                {
                    do
                    {
                        AIDone = false;
                        AIPicked = AIGenerator.Next(1, 4);
                        switch (AIPicked)
                        {
                            
                            
                            case 1 : 
                                if (freddyTaken == false)
                                {
                                    freddyTaken = true;
                                    Players[numPlayers + i - 1].isRealPerson = false;
                                    Players[numPlayers + i - 1].name = "Fast Freddy";
                                    Players[numPlayers + i - 1].preference = "b";
                                    
                                    AIDone = true;
                                }
                                break;
                            case 2 :
                                if (eddieTaken == false)
                                {
                                    eddieTaken = true;
                                    Players[numPlayers + i - 1].isRealPerson = false;
                                    Players[numPlayers + i - 1].name = "Evil Eddie";
                                    Players[numPlayers + i - 1].preference = "s";
                                    AIDone = true;
                                }
                                break;
                            case 3 :
                                if (rodneyTaken == false)
                                {
                                    rodneyTaken = true;
                                    Players[numPlayers + i - 1].isRealPerson = false;
                                    Players[numPlayers + i - 1].name = "Random Rodney";
                                    Players[numPlayers + i - 1].preference = "r";
                                    AIDone = true;
                                }
                                break;
                        }
                    } while (AIDone == false);
                }
            }
            for (int k = 1; k < numAIPlayers + 1; k++)
            {
                switch (Players[numPlayers + k - 1].name)
                {
                    case "Fast Freddy" :
                        Console.ForegroundColor = ConsoleColor.Black;
                        Console.WriteLine();
                        Console.WriteLine("Enter Player" + (4 - numAIPlayers + k) + "'s name");
                        
                        for (int j = 1; j < (Players[numPlayers + k - 1].name.Length + 1); j++)
                        {
                            Console.Write(Players[numPlayers + k - 1].name.Substring(j-1,1));
                            Thread.Sleep(50);
                        }
                        Console.WriteLine();
                        break;
                        
                    case "Random Rodney" :
                        Console.ForegroundColor = ConsoleColor.Black;
                        Console.WriteLine();
                        Console.WriteLine("Enter Player" + (4-numAIPlayers + k) + "'s name");
                        for (int j = 1; j < (Players[numPlayers + k - 1].name.Length + 1); j++)
                        {
                            
                            switch (AIGenerator.Next(1,16))
                            {
                                case 1 :
                                    Console.ForegroundColor = ConsoleColor.Blue;
                                    break;
                                case 2 :
                                    Console.ForegroundColor = ConsoleColor.Cyan;
                                    break;
                                case 3 :
                                    Console.ForegroundColor = ConsoleColor.DarkBlue;
                                    break;
                                case 4 :
                                    Console.ForegroundColor = ConsoleColor.DarkCyan;
                                    break;
                                case 5 :
                                    Console.ForegroundColor = ConsoleColor.DarkGray;
                                    break;
                                case 6 :
                                    Console.ForegroundColor = ConsoleColor.DarkGreen;
                                    break;
                                case 7 :
                                    Console.ForegroundColor = ConsoleColor.DarkMagenta;
                                    break;
                                case 8 :
                                    Console.ForegroundColor = ConsoleColor.DarkRed;
                                    break;
                                case 9 :
                                    Console.ForegroundColor = ConsoleColor.DarkYellow;
                                    break;
                                case 10 :
                                    Console.ForegroundColor = ConsoleColor.Gray;
                                    break;
                                case 11 :
                                    Console.ForegroundColor = ConsoleColor.Green;
                                    break;
                                case 12 :
                                    Console.ForegroundColor = ConsoleColor.Magenta;
                                    break;
                                case 13 :
                                    Console.ForegroundColor = ConsoleColor.Red;
                                    break;
                                case 14 :
                                    Console.ForegroundColor = ConsoleColor.Black;
                                    break;
                                case 15 :
                                    Console.ForegroundColor = ConsoleColor.Red;
                                    break;
                            }
                            
                            
                            switch (AIGenerator.Next(1, 3))
                            {
                                case 1 : 
                                    Console.Write(Players[numPlayers + k - 1].name.Substring(j-1,1).ToUpper());
                                    break;
                                case 2 :
                                    Console.Write(Players[numPlayers + k - 1].name.Substring(j - 1, 1).ToLower());
                                    break;
                                    
                            }
                            
                            
                            Thread.Sleep(250);
                        }
                        Console.WriteLine();
                        break;
                    case "Evil Eddie" :
                        Console.ForegroundColor = ConsoleColor.Black;
                        Console.WriteLine();
                        Console.WriteLine("Enter Player" + (4-numAIPlayers + k) + "'s name");
                        for (int j = 1; j < (Players[numPlayers + k - 1].name.Length + 1); j++)
                        {
                            Console.ForegroundColor = ConsoleColor.Red;
                            Console.Write(Players[numPlayers + k - 1].name.Substring(j-1,1));
                            Thread.Sleep(250);
                        }
                        Console.ForegroundColor = ConsoleColor.Gray;
                        Console.WriteLine();
                        break;
                }
            }
            Console.ForegroundColor = ConsoleColor.Black;
            Console.WriteLine();
            Console.WriteLine("___________________________________________");
            Console.WriteLine();
            Console.ReadLine();
#endregion
            do
            {
                Console.Clear();
                #region MainGameLogic
                #region TheRoll
                if (Players[turn].num6s > 0)
                Console.WriteLine("You rolled a 6, you get to roll again!");
                Console.Write("It is ");
                switch (Players[turn].name)
                {
                    case "Evil Eddie" :
                        Console.ForegroundColor = ConsoleColor.Red;
                        Console.Write("Evil Eddie");
                        Console.ForegroundColor = ConsoleColor.Black;
                        break;
                    case "Fast Freddy" :
                        Console.Write("Fast Freddy");
                        break;
                    case "Random Rodney" :
                        for (int j = 1; j < (Players[turn].name.Length + 1); j++)
                        {
                            switch (AIGenerator.Next(1, 16))
                            {
                                case 1:
                                    Console.ForegroundColor = ConsoleColor.Blue;
                                    break;
                                case 2:
                                    Console.ForegroundColor = ConsoleColor.Cyan;
                                    break;
                                case 3:
                                    Console.ForegroundColor = ConsoleColor.DarkBlue;
                                    break;
                                case 4:
                                    Console.ForegroundColor = ConsoleColor.DarkCyan;
                                    break;
                                case 5:
                                    Console.ForegroundColor = ConsoleColor.DarkGray;
                                    break;
                                case 6:
                                    Console.ForegroundColor = ConsoleColor.DarkGreen;
                                    break;
                                case 7:
                                    Console.ForegroundColor = ConsoleColor.DarkMagenta;
                                    break;
                                case 8:
                                    Console.ForegroundColor = ConsoleColor.DarkRed;
                                    break;
                                case 9:
                                    Console.ForegroundColor = ConsoleColor.DarkYellow;
                                    break;
                                case 10:
                                    Console.ForegroundColor = ConsoleColor.Gray;
                                    break;
                                case 11:
                                    Console.ForegroundColor = ConsoleColor.Green;
                                    break;
                                case 12:
                                    Console.ForegroundColor = ConsoleColor.Magenta;
                                    break;
                                case 13:
                                    Console.ForegroundColor = ConsoleColor.Red;
                                    break;
                                case 14:
                                    Console.ForegroundColor = ConsoleColor.Black;
                                    break;
                                case 15:
                                    Console.ForegroundColor = ConsoleColor.Red;
                                    break;
                            }
                            switch (AIGenerator.Next(1, 3))
                            {
                                case 1:
                                    Console.Write(Players[turn].name.Substring(j - 1, 1).ToUpper());
                                    break;
                                case 2:
                                    Console.Write(Players[turn].name.Substring(j - 1, 1).ToLower());
                                    break;
                            }
                            
                        }
                        Console.ForegroundColor = ConsoleColor.Black;
                        break;
                    default :
                        Console.Write(Players[turn].name);
                        Console.ForegroundColor = ConsoleColor.Black;
                        break;
                    
                        
                }
                Console.WriteLine("'s turn");
                Console.WriteLine(Players[turn].name + " you are currently on square: " + Players[turn].CurPos);
                Console.WriteLine("Press any key to roll... ");
                Console.ReadLine();
                roll = DiceRoll();
                
                Console.WriteLine("You rolled: " + roll);
                if ((Players[turn].CurPos + roll) == 64)
                {
                    
                    Console.WriteLine(Players[turn].name + " is the best Evil Squash player and has squashed the following: ");
                    for (int i = 0; i < Players.Length; i++)
                    {
                        if (i == turn)
                        {
                        }
                        else
                        {
                            Console.WriteLine(Players[i].name);
                        }
                    }
                    break;
                }
                if ((Players[turn].CurPos + roll) > 64)
                {
                    Console.WriteLine("You have rolled greater than 64 so you don't move this round");
                    Console.WriteLine("Press any key to end turn...");
                    Console.ReadLine();
                    if (turn + 1 == 4)
                        turn = 0;
                    else
                        turn = turn + 1;
                    continue;
                }
                Players[turn].prevprevPos = Players[turn].prevPos;
                Players[turn].prevPos = Players[turn].CurPos;
                Players[turn].CurPos = Players[turn].CurPos + roll;
                if (roll == 6)
                    Players[turn].num6s++;
                else
                    Players[turn].num6s = 0;
                if (Players[turn].num6s == 3)
                {
                    Console.WriteLine("You have rolled three sixes in a row, you go back to the start!");
                    Players[turn].CurPos = 0;
                    Players[turn].num6s = 0;
                    ThreeSixesRolled = true;
                    
                }
                #region SquashOrBounce
                SquashOrBounceMeth();
                #endregion
                #endregion
                #region AverageRoll
                if (Players[turn].numTurns == 0)
                {
                    Players[turn].AvgRoll = roll;
                    Players[turn].numTurns = 1;
                }
                else
                {
                    Players[turn].AvgRoll = ((Players[turn].AvgRoll * Players[turn].numTurns) + roll) / (Players[turn].numTurns + 1);
                    Players[turn].numTurns += 1;
                }
                Console.WriteLine("Your average roll is: " + Players[turn].AvgRoll);
                #endregion
                #region LandOnArrow
                if (ThreeSixesRolled == true)
                {
                }
                else
                {
                    if (MainTiles[(Players[turn].CurPos) - 1].special == true)
                    {
                        Console.WriteLine("You landed on an arrow!");
                        Console.WriteLine("You will now go to square: " + MainTiles[(Players[turn].CurPos) - 1].toWhere);
                        Players[turn].CurPos = MainTiles[(Players[turn].CurPos) - 1].toWhere;
                        SquashOrBounceMeth();
                    }
                }
                #endregion
                ThreeSixesRolled = false;
                Console.WriteLine("You are now on square: " + Players[turn].CurPos);
                Console.WriteLine("Press any key to end turn...");
                Console.WriteLine("___________________________________________");
                Console.WriteLine("");
                Console.ReadLine();
                if (Players[turn].num6s > 0)
                    continue;
                if (turn + 1 == 4)
                    turn = 0;
                else
                    turn = turn + 1;
                #endregion
            } while (!gameEnd);
        }
        static int DiceRoll()
        {
            Random Dice = new Random();
            return Dice.Next(1,7);
            //return 6;
            
        }
        static void numPlayerGetter()
        {
            
            Console.WriteLine("Welcome to Evil Squash!");
            Console.WriteLine("How many players will be playing (1-4): ");
            string strnumPlayers = Console.ReadLine();
            switch (strnumPlayers)
            {
                #region casePlayerSelector
                case "1":
                    numPlayers = 1;
                    break;
                case "2":
                    numPlayers = 2;
                    break;
                case "3":
                    numPlayers = 3;
                    break;
                case "4":
                    numPlayers = 4;
                    break;
                default:
                    Console.WriteLine("That is not a valid entry. Please enter 1-4.");
                    numPlayerGetter();
                    break;
                #endregion
            }
        }
    }
}