Example #1
0
        private static float PlayBestGlobalMove(int[, , ,] Cells, int player, ref int Bc, ref int Br, out int Cc, out int Cr, ref int age, int maxAge)
        {
            List <int> availableBc = new List <int>();
            List <int> availableBr = new List <int>();
            List <int> availableCc = new List <int>();
            List <int> availableCr = new List <int>();

            Cc = -1;
            Cr = -1;

            if (age > maxAge)
            {
                float wins  = 0;
                float loses = 0;
                for (int i = 0; i < 3; i++)
                {
                    for (int j = 0; j < 3; j++)
                    {
                        if (
                            Cells[i, j, 0, 0] + Cells[i, j, 0, 1] + Cells[i, j, 0, 2] == player * 3 ||
                            Cells[i, j, 1, 0] + Cells[i, j, 1, 1] + Cells[i, j, 1, 2] == player * 3 ||
                            Cells[i, j, 2, 0] + Cells[i, j, 2, 1] + Cells[i, j, 2, 2] == player * 3 ||
                            Cells[i, j, 0, 0] + Cells[i, j, 1, 0] + Cells[i, j, 2, 0] == player * 3 ||
                            Cells[i, j, 0, 1] + Cells[i, j, 1, 1] + Cells[i, j, 2, 1] == player * 3 ||
                            Cells[i, j, 0, 2] + Cells[i, j, 1, 2] + Cells[i, j, 2, 2] == player * 3 ||
                            Cells[i, j, 0, 0] + Cells[i, j, 1, 1] + Cells[i, j, 2, 2] == player * 3 ||
                            Cells[i, j, 0, 2] + Cells[i, j, 1, 1] + Cells[i, j, 2, 0] == player * 3
                            )
                        {
                            wins++;
                        }
                        else if (
                            Cells[i, j, 0, 0] + Cells[i, j, 0, 1] + Cells[i, j, 0, 2] == -1 * player * 3 ||
                            Cells[i, j, 1, 0] + Cells[i, j, 1, 1] + Cells[i, j, 1, 2] == -1 * player * 3 ||
                            Cells[i, j, 2, 0] + Cells[i, j, 2, 1] + Cells[i, j, 2, 2] == -1 * player * 3 ||
                            Cells[i, j, 0, 0] + Cells[i, j, 1, 0] + Cells[i, j, 2, 0] == -1 * player * 3 ||
                            Cells[i, j, 0, 1] + Cells[i, j, 1, 1] + Cells[i, j, 2, 1] == -1 * player * 3 ||
                            Cells[i, j, 0, 2] + Cells[i, j, 1, 2] + Cells[i, j, 2, 2] == -1 * player * 3 ||
                            Cells[i, j, 0, 0] + Cells[i, j, 1, 1] + Cells[i, j, 2, 2] == -1 * player * 3 ||
                            Cells[i, j, 0, 2] + Cells[i, j, 1, 1] + Cells[i, j, 2, 0] == -1 * player * 3
                            )
                        {
                            loses++;
                        }
                    }
                }
                return((wins - loses) / 9);
                // instead retun a franction between -1 and 1 based on finished boards
            }


            FindAvailableMoves(Cells, Bc, Br, availableBc, availableBr, availableCc, availableCr);

            if (availableBc.Count == 0)
            {
                return(0);
                // instead retun a franction between -1 and 1 based on finished boards
            }

            float bestScore = -10;
            int   bestAge   = 0;

            for (int i = 0; i < availableBc.Count; i++)
            {
                int   localAge = age;
                float score    = -10;
                //int[,,,] cells = new int[3, 3, 3, 3];
                GameEngine localEngine = new GameEngine();
                localEngine.NextPlayer = player;
                int cc, cr;
                Array.Copy(Cells, localEngine.Cells, Cells.Length);
                // do not call the next line for a less smart AI
                localEngine.recalculateBoards();
                MoveState res = localEngine.PlayMove(player, availableBc[i], availableBr[i], availableCc[i], availableCr[i]);
                localAge++;

                if (res == MoveState.SUCCESS_BOARD_WON_GAME_WON || res == MoveState.SUCCESS_BOARD_DRAW_GAME_WON)
                {
                    score = 1;
                }
                else if (res == MoveState.SUCCESS_BOARD_WON_GAME_LOST || res == MoveState.SUCCESS_BOARD_DRAW_GAME_LOST)
                {
                    score = -1;
                }
                else if (!localEngine.IsMoveSuccess(res))
                {
                    break;
                }
                else
                {
                    score = -1 * PlayBestGlobalMove(localEngine.Cells, -1 * player, ref localEngine.NextBoardCol, ref localEngine.NextBoardRow, out cc, out cr, ref localAge, maxAge);
                }

                if (score > bestScore || (bestScore != 1 && score == bestScore && localAge >= bestAge) || (bestScore == 1 && score == bestScore && localAge <= bestAge))
                {
                    if (localAge == bestAge && score == bestScore)
                    {
                        if (new Random().Next() % 2 == 0)
                        {
                            bestScore = score;
                            Bc        = availableBc[i];
                            Br        = availableBr[i];
                            Cc        = availableCc[i];
                            Cr        = availableCr[i];
                            bestAge   = localAge;
                        }
                    }
                    else
                    {
                        bestScore = score;
                        Bc        = availableBc[i];
                        Br        = availableBr[i];
                        Cc        = availableCc[i];
                        Cr        = availableCr[i];
                        bestAge   = localAge;
                    }
                }
            }

            age = bestAge;
            return(bestScore);
        }