@name minimax
@inputs
@outputs
@persist Game:table
@trigger none

if (first()) {
    function table new_game() {
        return table(
            array(0, 0, 0, 0, 0, 0, 0),
            array(0, 0, 0, 0, 0, 0, 0),
            array(0, 0, 0, 0, 0, 0, 0),
            array(0, 0, 0, 0, 0, 0, 0),
            array(0, 0, 0, 0, 0, 0, 0),
            array(0, 0, 0, 0, 0, 0, 0)
        )
    }

    function number table:can_insert( Col ) {
        for (R = 1, 6) {
            if (This[R, array][Col, number] != 0) {
                return R - 1
            }
        }
        return 6
    }

    function number table:do_insert( Row, Col, Val ) {
        This[Row, array][Col, number] = Val
    }

    function table:do_remove( Row, Col ) {
        This[Row, array][Col, number] = 0
    }

    MaxDepth  = 1
    MaxColumn = 0
    PlayerA = 2
    PlayerB = 4

    EvaluationTable = table(
        array(3, 4,  5, 7,   5, 4, 3),
        array(4, 6,  8, 10,  8, 6, 4),
        array(5, 8, 11, 13, 11, 8, 5),
        array(5, 8, 11, 13, 11, 8, 5),
        array(4, 6,  8, 10,  8, 6, 4),
        array(3, 4,  5,  7,  5, 4, 3)
    )

    function number table:evaluate() {
        local Util = 128
        local Sum  = 0

        for (R = 1, 6) {
            for (C = 1, 7) {
                local Value = This[R, array][C, number]
                if (Value == PlayerA) {
                    Sum += EvaluationTable[R, array][C, number]
                }
                elseif (Value == PlayerB) {
                    Sum -= EvaluationTable[R, array][C, number]
                }
            }
        }

        return Util + Sum
    }


    function number minimax( State:table, Depth, Player ) {
        if (Depth == MaxDepth) {
            return State:evaluate()
        }

        Depth++

        if (Player == PlayerA) {
            local Max = -10000
            local Col = 0

            for (I = 1, 7) {
                local Legal = State:can_insert(I)
                if (Legal > 0) {
                    State:do_insert(Legal, I, Player)

                    local Value = minimax(State, Depth, PlayerB)
                    if (Max < Value) {
                        Max = Value
                        Col = I
                    }

                    State:do_remove(Legal, I)
                }
            }
            MaxColumn = Col
            return Max
        }
        else {
            local Min = 10000
            for (I = 1, 7) {
                local Legal = State:can_insert(I)
                if (Legal > 0) {
                    State:do_insert(Legal, I, Player)

                    local Value = minimax(State, Depth, PlayerA)
                    if (Min > Value) {
                        Min = Value
                    }

                    State:do_remove(Legal, I)
                }
            }

            return Min
        }
    }

    Test = new_game()
    print(minimax( Test, 0, PlayerA ))

    print(MaxColumn)
}
#
