Пример #1
0
 HOLESTATE[] rotate(HOLESTATE[] gb, Pentago_Move move)
 {
     HOLESTATE[] new_gb = (HOLESTATE[])gb.Clone();
     if (move.rotDir == Pentago_Move.rotate_clockwise)
     {
         for (int x = 0; x < 3; ++x)
         {
             for (int y = 0; y < 3; ++y)
             {
                 new_gb[Pentago_GameBoard.board_position_to_index(Math.Abs(2 - y), x, move.square2rotate)]
                     = gb[Pentago_GameBoard.board_position_to_index(x, y, move.square2rotate)];
             }
         }
     }
     else
     {
         for (int x = 0; x < 3; ++x)
         {
             for (int y = 0; y < 3; ++y)
             {
                 new_gb[Pentago_GameBoard.board_position_to_index(y, Math.Abs(2 - x), move.square2rotate)]
                     = gb[Pentago_GameBoard.board_position_to_index(x, y, move.square2rotate)];
             }
         }
     }
     return(new_gb);
 }
Пример #2
0
 void bakeMovesMainDiagAbove()
 {
     MovesMainDiagAbove    = new Pentago_Move[21];
     MovesMainDiagAbove[0] = all_possible_place_piece_moves[Pentago_GameBoard.board_position_to_index(0, 0, 0)];
     MovesMainDiagAbove[1] = all_possible_place_piece_moves[Pentago_GameBoard.board_position_to_index(1, 0, 0)];
     MovesMainDiagAbove[2] = all_possible_place_piece_moves[Pentago_GameBoard.board_position_to_index(2, 0, 0)];
     MovesMainDiagAbove[3] = all_possible_place_piece_moves[Pentago_GameBoard.board_position_to_index(1, 1, 0)];
     MovesMainDiagAbove[4] = all_possible_place_piece_moves[Pentago_GameBoard.board_position_to_index(2, 1, 0)];
     MovesMainDiagAbove[5] = all_possible_place_piece_moves[Pentago_GameBoard.board_position_to_index(2, 2, 0)];
     for (int i = 6; i < 15; i++)
     {
         for (int x = 0; x < 3; x++)
         {
             for (int y = 0; y < 3; y++)
             {
                 MovesMainDiagAbove[i] = new Pentago_Move(x, y, 1);
             }
         }
     }
     MovesMainDiagAbove[15] = all_possible_place_piece_moves[Pentago_GameBoard.board_position_to_index(0, 0, 3)];
     MovesMainDiagAbove[16] = all_possible_place_piece_moves[Pentago_GameBoard.board_position_to_index(1, 0, 3)];
     MovesMainDiagAbove[17] = all_possible_place_piece_moves[Pentago_GameBoard.board_position_to_index(2, 0, 3)];
     MovesMainDiagAbove[18] = all_possible_place_piece_moves[Pentago_GameBoard.board_position_to_index(1, 1, 3)];
     MovesMainDiagAbove[19] = all_possible_place_piece_moves[Pentago_GameBoard.board_position_to_index(2, 1, 3)];
     MovesMainDiagAbove[20] = all_possible_place_piece_moves[Pentago_GameBoard.board_position_to_index(2, 2, 3)];
 }
Пример #3
0
    static public void testMinMax()
    {
        initialize_test_gameboards();
        Pentago_Rules wrules = new Pentago_Rules(Pentago_Rules.EvaluationFunction.control,
                                                 Pentago_Rules.NextStatesFunction.all_states,
                                                 Pentago_Rules.IA_PIECES_WHITES, false);
        MINMAX        test_w = new MINMAX(MINMAX.VERSION.minmax, wrules, 6);
        Pentago_Rules brules = new Pentago_Rules(Pentago_Rules.EvaluationFunction.control,
                                                 Pentago_Rules.NextStatesFunction.all_states,
                                                 Pentago_Rules.IA_PIECES_BLACKS, false);
        MINMAX test_b = new MINMAX(MINMAX.VERSION.minmax, brules, 6);
        bool?  player;

        boardMinMax.print_board();
        while (!boardMinMax.game_ended(out player))
        {
#if DEBUG_MIN_MAX
            alpha_beta_test.debugBoard = (o) => { o.print_board(); };
#endif
            applyPrintMoves2(test_w.run(boardMinMax));
#if PLAY_AGAINST_MIN_MAX
            Console.WriteLine("Place a piece: square,x,y     square E[0,3]      x,y E[0,2]");
            int[]        input = Console.ReadLine().Split(',').Select <string, int>(o => Convert.ToInt32(o)).ToArray();
            Pentago_Move pm    = new Pentago_Move(input[0], input[1], input[2]);
            pm.apply_move2board(boardAlphaBeta);
            Console.WriteLine("Rotate a square: square,dir     square E[0,3]      dir E[0-anti,1-clock]");
            input = Console.ReadLine().Split(',').Select <string, int>(o => Convert.ToInt32(o)).ToArray();
            pm    = new Pentago_Move(input[0], input[1] == 0 ? Pentago_Move.rotate_anticlockwise : Pentago_Move.rotate_clockwise);
            pm.apply_move2board(boardAlphaBeta);
            boardAlphaBeta.print_board();
#else
            applyPrintMoves2(test_b.run(boardMinMax));
#endif
        }
    }
Пример #4
0
    IEnumerator PLACE_PIECE_COUROUTINE()
    {
        yield return(null);

        GameObject newObj;

        if (gameboard.get_player_turn() == Pentago_GameBoard.whites_turn)
        {
            newObj = GameObject.Instantiate(whitePiecesPrefab);
        }
        else
        {
            newObj = GameObject.Instantiate(blackPiecesPrefab);
        }

        newObj.transform.position = new_piece_hole.transform.position;
        newObj.transform.parent   = squares[square2placePiece].transform;

        if (gameboard.game_ended(out winning_player))
        {
            gameState = GAME_STATE.ended;
        }
        else //if game did not end
        {
            if (gameState == GAME_STATE.playerselecthole)
            {
                gameState = GAME_STATE.playerselectrotation;
                ShowRotationGUI();
            }
            if (gameState == GAME_STATE.IAplacepiece)
            {
                if (iaThread.moves.Length < 2)
                {
                    Debug.LogError("IA did not decided on rotation!!!");
                }
                Pentago_Move rotate_move = iaThread.moves[1];
                setRotationSquare(rotate_move.square2rotate);
                rotateSquare(rotate_move.rotDir == Pentago_Move.rotate_clockwise);
                //done on apply rotation -> rotate_move.apply_move2board(gameboard);
                gameState = GAME_STATE.IArotatequare;
            }
            if (gameState == GAME_STATE.IAplacepiece2)
            {
                if (iaThread2.moves.Length < 2)
                {
                    Debug.LogError("2nd IA did not decided on rotation!!!");
                }
                Pentago_Move rotate_move = iaThread2.moves[1];
                setRotationSquare(rotate_move.square2rotate);
                rotateSquare(rotate_move.rotDir == Pentago_Move.rotate_clockwise);
                //done on apply rotation -> rotate_move.apply_move2board(gameboard);
                gameState = GAME_STATE.IArotatequare2;
            }
        }

        GAMESUBSTATE_IS_PLACING_PIECE = false;
    }
Пример #5
0
    static public void testAlphaBeta()
    {
        initialize_test_gameboards();
        Pentago_Rules wrules = new Pentago_Rules(Pentago_Rules.EvaluationFunction.oneDotTwo,
                                                 Pentago_Rules.NextStatesFunction.all_states,
                                                 Pentago_Rules.IA_PIECES_WHITES, false);
        MINMAX        alpha_beta_test_w = new MINMAX(MINMAX.VERSION.alphabeta, wrules, 0);
        Pentago_Rules brules            = new Pentago_Rules(Pentago_Rules.EvaluationFunction.A,
                                                            Pentago_Rules.NextStatesFunction.all_states,
                                                            Pentago_Rules.IA_PIECES_BLACKS, false);
        MINMAX alpha_beta_test_b = new MINMAX(MINMAX.VERSION.alphabeta, brules, 0);
        bool?  player;

/*        boardAlphaBeta.print_board();
 *      Console.WriteLine("|-|-|-|-|-|-|-|-|");*/
        while (!emptyBoard.game_ended(out player))
        {
#if DEBUG_ALPHA_BETA
            alpha_beta_test.debugBoard = (o) => { o.print_board(); };
#endif
            applyPrintMoves(alpha_beta_test_w.run(emptyBoard), emptyBoard);
            Console.WriteLine("|-|-|-|-|-|-|-|-|");
#if PLAY_AGAINST_HUMAN
            Console.WriteLine("Place a piece: square,x,y     square E[0,3]      x,y E[0,2]");
            int[]        input = Console.ReadLine().Split(',').Select <string, int>(o => Convert.ToInt32(o)).ToArray();
            Pentago_Move pm    = new Pentago_Move(input[0], input[1], input[2]);
            pm.apply_move2board(boardAlphaBeta);
            Console.WriteLine("Rotate a square: square,dir     square E[0,3]      dir E[0-anti,1-clock]");
            input = Console.ReadLine().Split
                        (',').Select <string, int>(o => Convert.ToInt32(o)).ToArray();
            pm = new Pentago_Move(input[0], input[1] == 0 ? Pentago_Move.rotate_anticlockwise : Pentago_Move.rotate_clockwise);
            pm.apply_move2board(boardAlphaBeta);
            boardAlphaBeta.print_board();
#else
            applyPrintMoves(alpha_beta_test_b.run(emptyBoard), emptyBoard);
            Console.WriteLine("|-|-|-|-|-|-|-|-|");
#endif
        }
        if (player == null)
        {
            Console.WriteLine("Tie");
        }
        else if (player == Pentago_Rules.IA_PIECES_BLACKS)
        {
            Console.WriteLine("Black wins");
        }
        else
        {
            Console.WriteLine("White wins");
        }
    }
Пример #6
0
    HOLESTATE[] get_rotated_board_90deg_anticlockwise(HOLESTATE[] board)
    {
        HOLESTATE[] newboard = new HOLESTATE[36];

        copy_square2(board, newboard, 0, 2);
        copy_square2(board, newboard, 1, 0);
        copy_square2(board, newboard, 2, 3);
        copy_square2(board, newboard, 3, 1);

        Pentago_Move rotsquares = new Pentago_Move(0, Pentago_Move.rotate_anticlockwise);

        rotsquares.move(newboard, true, Pentago_GameBoard.turn_state_rotate);
        rotsquares.square2rotate = 1; rotsquares.move(newboard, true, Pentago_GameBoard.turn_state_rotate);
        rotsquares.square2rotate = 2; rotsquares.move(newboard, true, Pentago_GameBoard.turn_state_rotate);
        rotsquares.square2rotate = 3; rotsquares.move(newboard, true, Pentago_GameBoard.turn_state_rotate);

        return(newboard);
    }
Пример #7
0
    bool ApplyRotation()
    {
        if (squareRotating.HasValue)
        {
            rotatation_animation_frame += Time.deltaTime;

            float rotatation_animation;
            if (rotatation_animation_frame >= rotDuration)
            {
                rotatation_animation = 1.0f;
            }
            else
            {
                rotatation_animation =
                    rotatation_animation_frame > halfRotDuration ?
                    1.0f - .5f * Mathf.Pow((rotDuration - rotatation_animation_frame) / halfRotDuration, animRotPow)
                : 0.5f * Mathf.Pow(rotatation_animation_frame / halfRotDuration, animRotPow)
                ;
            }

            squares[squareRotating.Value].transform.localRotation = Quaternion.Slerp(
                previousRotation,
                default_rotations[squares_dest_rot[squareRotating.Value]],
                rotatation_animation);

            //float angle = Quaternion.Angle(squares[squareRotating.Value].transform.localRotation,
            //    default_rotations[squares_dest_rot[squareRotating.Value]]);

            squares[squareRotating.Value].transform.localPosition = new Vector3(squares[squareRotating.Value].transform.localPosition.x,
                                                                                default_y_position.y + maxHigh * Mathf.Pow((.5f - Mathf.Abs(.5f - rotatation_animation)) * 2, animRotPow)
                                                                                , squares[squareRotating.Value].transform.localPosition.z);

            if (rotatation_animation_frame >= rotDuration)
            {
                rotatation_animation_frame = 0.0f;
                Pentago_Move move = new Pentago_Move(squareRotating.Value, rotation_direction);
                move.apply_move2board(gameboard);
                squareRotating = null;
                return(true);//rotation completed
            }
        }
        return(false);
    }
Пример #8
0
    Pentago_Move[] getMoves(int[] squares)
    {
        Pentago_Move[] moves = new Pentago_Move[squares.Length * 9];
        int            i     = 0;

        foreach (int s in squares)
        {
            for (int x = 0; x < 3; x++)
            {
                for (int y = 0; y < 3; y++)
                {
                    moves[i] = all_possible_place_piece_moves[Pentago_GameBoard.board_position_to_index(x, y, s)];
                    //moves[i] = new Pentago_Move(s, x, y);
                    i++;
                }
            }
        }

        return(moves);
    }
Пример #9
0
    private bool generateNewMove(ref HOLESTATE [] test_board)
    {
        bool valid_move = false;
        int  count      = 0; // avoid infinit loop

        while (!valid_move)
        {
            int square = GetRandomNumber(0, 4); // creates a number between 0 and 4
            int x      = GetRandomNumber(0, 3);
            int y      = GetRandomNumber(0, 3);

            Pentago_Move new_move = new Pentago_Move(square, x, y);
            if (new_move.is_move_possible(Pentago_gb))
            {
                bool?        winning_player; // not needed
                HOLESTATE[]  temp   = (HOLESTATE[])test_board.Clone();
                HOLESTATE [] temp_1 = new_move.move(test_board, Pentago_gb.get_player_turn(), turn_state_addpiece);
                test_board = (HOLESTATE [])temp_1.Clone();

                if (!Pentago_gb.game_ended(out winning_player))
                {
                    valid_move = true;
                    break;
                }
                else
                {
                    test_board = (HOLESTATE[])temp.Clone();
                }
            }

            if (count == MAX_COUNT)
            {
                break;
            }
            count++;
        }
        return(valid_move);
    }
Пример #10
0
    bool GAMESUBSTATE_IS_PLACING_PIECE = false;//fast 'hacked solution', indicates when the placing of the piece is happening
    void PlayerPlacingPiece()
    {
        if (GAMESUBSTATE_IS_PLACING_PIECE)
        {
            return;
        }

        RaycastHit hit;
        Ray        ray = Camera.main.ScreenPointToRay(Input.mousePosition);

        if (Physics.Raycast(ray, out hit))
        {
            Hole objectHit = hit.transform.GetComponent <Hole>();
            if (objectHit != null)
            {
                if (Input.GetMouseButtonDown(0))
                {
                    Hole hole = objectHit.GetComponent <Hole>();
                    new_piece_hole    = hole.transform;
                    square2placePiece = Convert.ToInt32(hole.transform.parent.name.Substring(0, 1));

                    Pentago_Move mov = new Pentago_Move(square2placePiece, hole.x, hole.y);

                    if (mov.is_move_possible(gameboard))
                    {
                        mov.apply_move2board(gameboard);
                        visual_cue.intensity          = 0;
                        time2ShutLight                = 0;
                        lightOwned                    = false;
                        GAMESUBSTATE_IS_PLACING_PIECE = true;
                        StartCoroutine("PLACE_PIECE_COUROUTINE");
                        return;
                    }
                }

                if (previousCuedHole != null && previousCuedHole == objectHit.transform.gameObject || !lightOwned)
                {
                    time2ShutLight = maxtime2ShutLight;
                    visual_cue.transform.position = objectHit.transform.position;
                    lightOwned       = true;
                    previousCuedHole = objectHit.transform.gameObject;
                }
            }
        }


        if (time2ShutLight > 0)
        {
            if (visual_cue.intensity < maxLightIntensity)
            {
                visual_cue.intensity += lightupspeed * Time.deltaTime;
            }
            time2ShutLight -= Time.deltaTime;
        }
        else
        {
            if (visual_cue.intensity > 0)
            {
                visual_cue.intensity -= lightupspeed * Time.deltaTime;
            }
            else
            {
                lightOwned           = false;
                visual_cue.intensity = 0;
            }
        }
    }
Пример #11
0
    public static void play(int depth, Pentago_Rules.EvaluationFunction ef, Pentago_Rules.NextStatesFunction nsf, bool remove_duplicates, bool ia_pieces)
    {
        Pentago_GameBoard gb          = new Pentago_GameBoard();
        bool?         winning_player  = null;
        Pentago_Rules rules           = new Pentago_Rules(ef, nsf, ia_pieces, remove_duplicates);
        MINMAX        alpha_beta_test = new MINMAX(MINMAX.VERSION.alphabeta, rules, depth);
        Stopwatch     sw = new Stopwatch();

        while (!gb.game_ended(out winning_player))
        {
            gb.print_board();

            if (gb.get_player_turn() != ia_pieces)
            {
                Console.WriteLine("Your turn");
                if (gb.get_turn_state() == Pentago_GameBoard.turn_state_addpiece)
                {
                    Console.WriteLine("Place a piece: square,x,y     square E[0,3]      x,y E[0,2]");
                    int[] input;
                    try
                    {
                        input = Console.ReadLine().Split(',').Select <string, int>(o => Convert.ToInt32(o)).ToArray();
                        if (input.Length < 3)
                        {
                            continue;
                        }
                    }
                    catch { continue; }
                    Pentago_Move pm = new Pentago_Move(input[0], input[1], input[2]);
                    if (!pm.is_move_possible(gb))
                    {
                        continue;
                    }
                    pm.apply_move2board(gb);
                }
                else
                {
                    Console.WriteLine("Rotate a square: square,dir     square E[0,3]      dir E[0-anti,1-clock]");
                    int[] input;
                    try
                    {
                        input = Console.ReadLine().Split(',').Select <string, int>(o => Convert.ToInt32(o)).ToArray();
                        if (input.Length < 2)
                        {
                            continue;
                        }
                    }
                    catch { continue; }
                    Pentago_Move pm = new Pentago_Move(input[0], input[1] == 0 ? Pentago_Move.rotate_anticlockwise : Pentago_Move.rotate_clockwise);
                    if (!pm.is_move_possible(gb))
                    {
                        continue;
                    }
                    pm.apply_move2board(gb);
                }
            }
            else
            {
                Console.WriteLine("IA's turn");
                sw.Start();
                applyMoves(alpha_beta_test.run(gb), gb);
                sw.Stop();
                Console.WriteLine("Time={0}", sw.Elapsed);
            }
        }
        if (winning_player == null)
        {
            Console.WriteLine("\nGAME ENDED IN DRAW");
        }
        else if (winning_player != ia_pieces)
        {
            Console.WriteLine("\nGAME ENDED - YOU WON");
        }
        else
        {
            Console.WriteLine("\nGAME ENDED - IA WON");
        }
    }
Пример #12
0
    public static void play()
    {
        Pentago_GameBoard gb         = new Pentago_GameBoard();
        bool?         winning_player = null;
        Pentago_Rules rules          = new Pentago_Rules();

        rules.setHeuristic1Bias(0);

        while (!gb.game_ended(out winning_player))
        {
            Console.Clear();
            gb.print_board();

            if (gb.get_player_turn() == Pentago_GameBoard.whites_turn)
            {
                Pentago_GameBoard newbg     = gb;
                float             bestSoFar = float.NegativeInfinity;
                Pentago_Move[]    moves     = rules.possible_plays(gb);
                bool ended = false;
                //int count = 0;
                foreach (Pentago_Move move in moves)
                {
                    // Console.WriteLine(move.ToString());
                    Pentago_GameBoard gb_aux = move.state_after_move(gb);
                    // gb_aux.print_board();
                    // count++;
                    //  if (count > 5) break;
                    bool?winner;
                    if (gb_aux.game_ended(out winner))
                    {
                        if (winner != null && winner == Pentago_GameBoard.whites_turn)
                        {
                            move.apply_move2board(gb); ended = true;
                        }
                    }
                    if (ended)
                    {
                        break;
                    }

                    foreach (Pentago_GameBoard gbs in rules.next_states(gb_aux))
                    {
                        if (gbs.game_ended(out winner))
                        {
                            if (winner != null && winner == Pentago_GameBoard.whites_turn)
                            {
                                gb = gbs;  ended = true;
                            }
                        }
                        if (ended)
                        {
                            break;
                        }

                        float value = rules.heuristic1dot2(gbs.board);

                        if (value > bestSoFar)
                        {
                            bestSoFar = value;
                            newbg     = gbs;
                        }
                    }
                    if (ended)
                    {
                        break;
                    }
                }
                if (ended)
                {
                    break;
                }

                gb = newbg;

                continue;
            }
            else
            {
                Console.WriteLine("Black's turn");
            }

            if (gb.get_turn_state() == Pentago_GameBoard.turn_state_addpiece)
            {
                Console.WriteLine("Place a piece: square,x,y     square E[0,3]      x,y E[0,2]");
                int[] input;
                try {
                    input = Console.ReadLine().Split(',').Select <string, int>(o => Convert.ToInt32(o)).ToArray();
                    if (input.Length < 3)
                    {
                        continue;
                    }
                } catch { continue; }
                Pentago_Move pm = new Pentago_Move(input[0], input[1], input[2]);
                if (!pm.is_move_possible(gb))
                {
                    continue;
                }
                pm.apply_move2board(gb);
            }
            else
            {
                Console.WriteLine("Rotate a square: square,dir     square E[0,3]      dir E[0-anti,1-clock]");
                int[] input;
                try
                {
                    input = Console.ReadLine().Split(',').Select <string, int>(o => Convert.ToInt32(o)).ToArray();
                    if (input.Length < 2)
                    {
                        continue;
                    }
                }
                catch { continue; }
                Pentago_Move pm = new Pentago_Move(input[0], input[1] == 0? Pentago_Move.rotate_anticlockwise:Pentago_Move.rotate_clockwise);
                if (!pm.is_move_possible(gb))
                {
                    continue;
                }
                pm.apply_move2board(gb);
            }
        }

        Console.Clear();
        gb.print_board();
        if (winning_player == null)
        {
            Console.WriteLine("\nGAME ENDED IN DRAW");
        }
        else if (winning_player == Pentago_GameBoard.whites_turn)
        {
            Console.WriteLine("\nGAME ENDED - WHITE WON");
        }
        else
        {
            Console.WriteLine("\nGAME ENDED - BLACK WON");
        }
    }
Пример #13
0
 Pentago_GameBoard after_rotate(Pentago_GameBoard gb, Pentago_Move move)
 {
     return(new Pentago_GameBoard(rotate(gb.board, move), gb.get_player_turn(), gb.get_turn_state()));
 }
Пример #14
0
    public static void play()
    {
        Pentago_GameBoard gb = new Pentago_GameBoard();
        bool?winning_player  = null;

        while (!gb.game_ended(out winning_player))
        {
            Console.Clear();
            gb.print_board();

            if (gb.get_player_turn() == Pentago_GameBoard.whites_turn)
            {
                Console.WriteLine("White's turn");
            }
            else
            {
                Console.WriteLine("Black's turn");
            }

            if (gb.get_turn_state() == Pentago_GameBoard.turn_state_addpiece)
            {
                Console.WriteLine("Place a piece: square,x,y     square E[0,3]      x,y E[0,2]");
                int[] input;
                try {
                    input = Console.ReadLine().Split(',').Select <string, int>(o => Convert.ToInt32(o)).ToArray();
                    if (input.Length < 3)
                    {
                        continue;
                    }
                } catch { continue; }
                Pentago_Move pm = new Pentago_Move(input[0], input[1], input[2]);
                if (!pm.is_move_possible(gb))
                {
                    continue;
                }
                pm.apply_move2board(gb);
            }
            else
            {
                Console.WriteLine("Rotate a square: square,dir     square E[0,3]      dir E[0-anti,1-clock]");
                int[] input;
                try
                {
                    input = Console.ReadLine().Split(',').Select <string, int>(o => Convert.ToInt32(o)).ToArray();
                    if (input.Length < 2)
                    {
                        continue;
                    }
                }
                catch { continue; }
                Pentago_Move pm = new Pentago_Move(input[0], input[1] == 0? Pentago_Move.rotate_anticlockwise:Pentago_Move.rotate_clockwise);
                if (!pm.is_move_possible(gb))
                {
                    continue;
                }
                pm.apply_move2board(gb);
            }
        }

        Console.Clear();
        gb.print_board();
        if (winning_player == null)
        {
            Console.WriteLine("\nGAME ENDED IN DRAW");
        }
        else if (winning_player == Pentago_GameBoard.whites_turn)
        {
            Console.WriteLine("\nGAME ENDED - WHITE WON");
        }
        else
        {
            Console.WriteLine("\nGAME ENDED - BLACK WON");
        }
    }
Пример #15
0
    public static void play()
    {
        Pentago_GameBoard gb         = new Pentago_GameBoard();
        bool?         winning_player = null;
        Pentago_Rules brules         = new Pentago_Rules(Pentago_Rules.EvaluationFunction.heuristicA,
                                                         Pentago_Rules.NextStatesFunction.all_states,
                                                         Pentago_Rules.IA_PIECES_BLACKS, false);
        MINMAX alpha_beta_test_b = new MINMAX(MINMAX.VERSION.alphabeta, brules, 6);

        while (!gb.game_ended(out winning_player))
        {
            Console.Clear();
            gb.print_board();

            if (gb.get_player_turn() == Pentago_GameBoard.whites_turn)
            {
                Console.WriteLine("White's turn");
                if (gb.get_turn_state() == Pentago_GameBoard.turn_state_addpiece)
                {
                    Console.WriteLine("Place a piece: square,x,y     square E[0,3]      x,y E[0,2]");
                    int[] input;
                    try
                    {
                        input = Console.ReadLine().Split(',').Select <string, int>(o => Convert.ToInt32(o)).ToArray();
                        if (input.Length < 3)
                        {
                            continue;
                        }
                    }
                    catch { continue; }
                    Pentago_Move pm = new Pentago_Move(input[0], input[1], input[2]);
                    if (!pm.is_move_possible(gb))
                    {
                        continue;
                    }
                    pm.apply_move2board(gb);
                }
                else
                {
                    Console.WriteLine("Rotate a square: square,dir     square E[0,3]      dir E[0-anti,1-clock]");
                    int[] input;
                    try
                    {
                        input = Console.ReadLine().Split(',').Select <string, int>(o => Convert.ToInt32(o)).ToArray();
                        if (input.Length < 2)
                        {
                            continue;
                        }
                    }
                    catch { continue; }
                    Pentago_Move pm = new Pentago_Move(input[0], input[1] == 0 ? Pentago_Move.rotate_anticlockwise : Pentago_Move.rotate_clockwise);
                    if (!pm.is_move_possible(gb))
                    {
                        continue;
                    }
                    pm.apply_move2board(gb);
                }
            }
            else
            {
                Console.WriteLine("Black's turn");
                applyPrintMoves(alpha_beta_test_b.run(gb), gb);
            }
        }

        Console.Clear();
        gb.print_board();
        if (winning_player == null)
        {
            Console.WriteLine("\nGAME ENDED IN DRAW");
        }
        else if (winning_player == Pentago_GameBoard.whites_turn)
        {
            Console.WriteLine("\nGAME ENDED - WHITE WON");
        }
        else
        {
            Console.WriteLine("\nGAME ENDED - BLACK WON");
        }
    }