using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

 

namespace ACSL3

{

    class Program

    {

        static void PrintHeader(ConsoleColor mColor)

        {

            Console.ForegroundColor = mColor;

            Console.WriteLine("ACSL Contest #3");

            Console.WriteLine("Senior Division");

            Console.WriteLine("Mancala");

            Console.WriteLine("Author: Philip Etter");

            Console.WriteLine("Written in C# (.NET 3.5)\n");

            Console.ForegroundColor = ConsoleColor.Gray;

        }

 

        static void Main(string[] args)

        {

            Console.Title = "ACSL Contest #3";

 

            PrintHeader(ConsoleColor.White);

 

            var game = new Game();

            game.Init();

 

            while (!game.bGameEnded)

                game.TakeTurn();

        }

    }

 

    enum MancalaBoardSpecial

    {

        A = 13, B = 14, None = -1

    }

 

    class MancalaBoard

    {

        public const int mA_Thresh = 5;

        public const int mB_Thresh = 11;

 

        public const int mDefaultStones = 4;

        private int[] mMancalaStones;

        private int mSlotA;

        private int mSlotB;

        public MancalaBoardSpecial mPlayer;

 

        public int this[int i]

        {

            get

            {

                if (i == (int)MancalaBoardSpecial.A)

                    return mSlotA;

                else if (i == (int)MancalaBoardSpecial.B)

                    return mSlotB;

 

                i--;

 

                return mMancalaStones[i];

            }

            set

            {

                if (i == (int)MancalaBoardSpecial.A)

                    mSlotA = value;

                else if (i == (int)MancalaBoardSpecial.B)

                    mSlotB = value;

                else

                {

                    i--;

 

                    mMancalaStones[i] = value;

                }

            }

        }

 

        public MancalaBoard()

        {

            mMancalaStones = new int[mB_Thresh + 1];

        }

 

        public void Fill()

        {

            int count = mMancalaStones.Length;

            for (int i = 0; i < count; i += 1)

                mMancalaStones[i] = mDefaultStones;

        }

 

        public void Move(int mJar)

        {

            mJar--;

 

            int i = mMancalaStones[mJar];

            mMancalaStones[mJar] = 0;

 

            mJar++;

 

            for (; i > 0; i--)

            {

                if (i != 0)

                {

                    if (mPlayer == MancalaBoardSpecial.A && mJar == mA_Thresh + 1)

                        mJar = (int)MancalaBoardSpecial.A;

                    else if (mJar == (int)MancalaBoardSpecial.A)

                        mJar = mA_Thresh + 1;

 

                    if (mPlayer == MancalaBoardSpecial.B && mJar == mB_Thresh + 1)

                        mJar = (int)MancalaBoardSpecial.B;

                    else if (mPlayer == MancalaBoardSpecial.A && mJar == mB_Thresh + 1)

                        mJar = 0;

                    else if (mJar == (int)MancalaBoardSpecial.B)

                        mJar = 0;

 

                    if (mJar > (int)MancalaBoardSpecial.B)

                        mJar = 0;

                }

 

                if (mJar <= mB_Thresh)

                {

                    mMancalaStones[mJar]++;

                    if (i != 0)

                        mJar++;

                }

                else if (mJar == (int)MancalaBoardSpecial.A)

                    mSlotA++;

                else if (mJar == (int)MancalaBoardSpecial.B)

                    mSlotB++;

            }

 

            if (mBoardEvent != null)

            {

                //if (mJar < (int)MancalaBoardSpecial.A)

                    //mJar++;

                mBoardEvent(mJar, this);

            }

        }

 

        public delegate void BoardEvent(int mJar, MancalaBoard board);

 

        public event BoardEvent mBoardEvent;

 

        public void Print()

        {

            Console.Write("\t");

            for (int i = mA_Thresh; i >= 0; i--)

            {

                Console.Write("[" + mMancalaStones[i].ToString() + "]" + " ");

            }

            Console.WriteLine("");

 

            Console.WriteLine("[" + mSlotA + "]\t\t\t\t\t[" + mSlotB + "]");

 

            Console.Write("\t");

            for (int i = mA_Thresh + 1; i <= mB_Thresh; i++)

            {

                Console.Write("[" + mMancalaStones[i].ToString() + "]" + " ");

            }

            Console.WriteLine("");

            Console.WriteLine("");

        }

    }

 

    class Game

    {

        public MancalaBoard mBoard;

        public MancalaBoardSpecial mLastPlayer = MancalaBoardSpecial.None;

 

        public int mSelected;

        public int mTarget;

 

        public bool bGameEnded;

        public bool bFail;

 

        public int mLastFinalJar;

 

        public bool bTurnExtended;

 

        private char[] mStringSplitSeperator = { ',', ' ' };

 

        public void TakeTurn()

        {

            Console.ForegroundColor = ConsoleColor.Yellow;

            if (mBoard.mPlayer == MancalaBoardSpecial.A)

                Console.Write("Player A's Turn");

            else

                Console.Write("Player B's Turn");

            if (mLastPlayer == mBoard.mPlayer)

            {

                Console.WriteLine(" (Extended)");

                bTurnExtended = true;

            }

            else

            {

                Console.WriteLine("");

                bTurnExtended = false;

            }

            Console.ForegroundColor = ConsoleColor.Gray;

           

            try

            {

                if (!bTurnExtended)

                {

                    Console.ForegroundColor = ConsoleColor.Green;

                    Console.Write("Input: ");

                    Console.ForegroundColor = ConsoleColor.Gray;

 

                    string[] mInput = Console.ReadLine().Split(mStringSplitSeperator, StringSplitOptions.RemoveEmptyEntries);

                    mSelected = Int32.Parse(mInput[0]);

                    if (mInput[1] == "A")

                        mTarget = (int)MancalaBoardSpecial.A;

                    else if (mInput[1] == "B")

                        mTarget = (int)MancalaBoardSpecial.B;

                    else

                        mTarget = Int32.Parse(mInput[1]);

 

                    Console.WriteLine("");

                }

                else

                {

                    // Continue from where player left off

                    mSelected = mLastFinalJar;

                }

            }

            catch (Exception e)

            {

                bFail = true;

                Console.ForegroundColor = ConsoleColor.Red;

                Console.WriteLine(e.Message);

                Console.ForegroundColor = ConsoleColor.Gray;

                Console.WriteLine("");

            }

            finally

            {

                if (!bFail)

                {

                    if (mSelected < (int)MancalaBoardSpecial.A)

                    {

                        if (mBoard[mSelected] == 0)

                        {

                            Console.ForegroundColor = ConsoleColor.Red;

                            Console.WriteLine("Umm...sorry, but there are no stones in bowl #" + mSelected + "\nPlease Renter");

                            Console.ForegroundColor = ConsoleColor.Gray;

                            Console.WriteLine("");

                        }

                        else

                        {

                            mLastPlayer = mBoard.mPlayer;

 

                            mBoard.Move(mSelected);

                            mBoard.Print();

 

                            if (mBoard.mPlayer != mLastPlayer)

                            {

                                Console.ForegroundColor = ConsoleColor.Red;

                                Console.Write("\nResult: ");

                                Console.ForegroundColor = ConsoleColor.Gray;

                                Console.WriteLine(mBoard[mTarget].ToString() + "\n");

                            }

                        }

                    }

                    else

                    {

                        Console.ForegroundColor = ConsoleColor.Red;

                        Console.WriteLine("Incorrect Input!");

                        Console.ForegroundColor = ConsoleColor.Gray;

                    }

                }

 

                bFail = false;

            }

        }

 

        public void Init()

        {

            mBoard = new MancalaBoard();

            mBoard.mPlayer = MancalaBoardSpecial.A;

 

            mBoard.mBoardEvent += new MancalaBoard.BoardEvent(BoardEvent);

 

            mBoard.Fill();

        }

 

        void BoardEvent(int mJar, MancalaBoard board)

        {

            mLastFinalJar = mJar;

 

            if (mJar != (int)MancalaBoardSpecial.A && mJar != (int)MancalaBoardSpecial.B)

            {

                if (board[mJar] != 1)

                {

                    if (board.mPlayer == MancalaBoardSpecial.A)

                    {

                        if (board[mJar] == MancalaBoard.mDefaultStones)

                            EndTurn();

                        //board[(int)MancalaBoardSpecial.A] += board[mJar];

                        //board[mJar] = 0;

                    }

                    else if (board.mPlayer == MancalaBoardSpecial.B)

                    {

                        if (board[mJar] == MancalaBoard.mDefaultStones)

                            EndTurn();

                        //board[(int)MancalaBoardSpecial.B] += board[mJar];

                        //board[mJar] = 0;

                    }

                }

                else

                    EndTurn();

            }

            else

                EndTurn();

        }

 

        void EndTurn()

        {

            if (mBoard.mPlayer == MancalaBoardSpecial.A)

                mBoard.mPlayer = MancalaBoardSpecial.B;

            else

                mBoard.mPlayer = MancalaBoardSpecial.A;

        }

    }

}