JULIA-OPENAI-API
Simon-Pierre Boucher
2024-09-14

Julia OpenAI OpenAI GPT-4 GPT-3

In [1]:
using JSON
using HTTP

# Fonction pour appeler l'API OpenAI
function call_openai_api(
    messages::Vector{Dict{String, Any}};  # Required argument
    model::String = "gpt-4",
    temperature::Float64 = 1.0,
    max_tokens::Int = 2048,
    top_p::Float64 = 1.0,
    frequency_penalty::Float64 = 0.0,
    presence_penalty::Float64 = 0.0
)
    # Récupérer la clé API depuis les variables d'environnement
    api_key = get(ENV, "OPENAI_API_KEY", "")

    if isempty(api_key)
        error("API key not found in environment variables. Please set OPENAI_API_KEY.")
    end

    url = "https://api.openai.com/v1/chat/completions"

    headers = [
        "Content-Type" => "application/json",
        "Authorization" => "Bearer $api_key"
    ]

    # Préparer le corps de la requête
    data = Dict(
        "model" => model,
        "messages" => messages,
        "temperature" => temperature,
        "max_tokens" => max_tokens,
        "top_p" => top_p,
        "frequency_penalty" => frequency_penalty,
        "presence_penalty" => presence_penalty
    )

    json_data = JSON.json(data)

    # Envoyer la requête POST à l'API OpenAI
    response = HTTP.post(url, headers; body = json_data)

    # Vérifier si la requête a réussi
    if response.status != 200
        error("API request failed: $(response.status) - $(String(response.body))")
    end

    # Parse la réponse JSON
    result = JSON.parse(String(response.body))
    return result
end
Out[1]:
call_openai_api (generic function with 1 method)
In [2]:
# Exemple d'utilisation de la fonction
messages = [
    Dict{String, Any}("role" => "system", "content" => "You are an assistant"),
    Dict{String, Any}("role" => "user", "content" => "Give me a julia code for snake game")
]
Out[2]:
2-element Vector{Dict{String, Any}}:
 Dict("role" => "system", "content" => "You are an assistant")
 Dict("role" => "user", "content" => "Give me a julia code for snake game")
In [3]:
# Appeler la fonction pour obtenir une réponse
response = call_openai_api(
    messages;  # Required argument
    model = "gpt-4",
    temperature = 1.0,
    max_tokens = 2048,
    top_p = 1.0,
    frequency_penalty = 0.0,
    presence_penalty = 0.0
)

# Afficher la réponse de l'assistant
println(response["choices"][1]["message"]["content"])
Sure, here's an example of how you can code a basic version of the Snake game in Julia using Curses module for console applications. 

```julia
using Curses

function game()
    scr = initscr()
    curs_set(0)
    start_color()
    init_pair(1, COLOR_GREEN, COLOR_BLACK)
    cbreak()
    keypad(stdscr, true)
    timeout(250)
    y_max, x_max = getmaxyx(scr)[2:3]
    w = newwin(30, 60, 0, 0)
    keypad(w, true)
    box(w, 0, 0)
    halfdelay(1)
    snake = [[10,10], [10,11], [10,12], [10,13]]
    direction = KEY_LEFT
    apple = [rand(1:28), rand(1:58)]
    points = 0

    for s in snake
        mvwaddch(w, s[1], s[2], "#"|COLOR_PAIR(1))
    end
    mvwaddch(w, apple[1], apple[2], "%"|COLOR_PAIR(1))
    wrefresh(w)
    while true
        direction = wgetch(w) == ERR ? direction : wgetch(w)
        if direction == KEY_UP && snake[end][1] != 1
            push!(snake, [snake[end][1]-1, snake[end][2]])
        elseif direction == KEY_DOWN && snake[end][1] != 28
            push!(snake, [snake[end][1]+1, snake[end][2]])
        elseif direction == KEY_LEFT && snake[end][2] != 1
            push!(snake, [snake[end][1], snake[end][2]-1])
        elseif direction == KEY_RIGHT && snake[end][2] != 58
            push!(snake, [snake[end][1], snake[end][2]+1])
        else
            break
        end

        if apple == snake[end]
            points += 1
            apple = [rand(1:28), rand(1:58)]
            mvwaddch(w, apple[1], apple[2], "%"|COLOR_PAIR(1))
        else
            s = popfirst!(snake)
            mvwaddch(w, s[1], s[2], " ")
        end

        for s in snake
            mvwaddch(w, s[1], s[2], "#"|COLOR_PAIR(1))
        end
        if in(snake[end], snake[1:end-1]) || points == 30
            break
        end
        box(w, 0, 0)
        wrefresh(w)
    end
    points = points == 30 ? "You won!" : "You lost!"
    clear(w)
    mvwprintw(w, 15, 30, points)
    wrefresh(w)
    napms(2000)
    endwin()
end

game()
```

Before you can run this you need to install the `Curses` package. If not installed, kindly install it by running `import Pkg; Pkg.add("Curses")` in julia prompt.

This game works in a console window, capturing input from arrow keys. Snake is represented by '#', apple by '%' and your score increments as you eat each apple.

And remember, this game will end if the snake touches the border or itself.
In [4]:
# Appeler la fonction pour obtenir une réponse
response = call_openai_api(
    messages;  # Required argument
    model = "gpt-4o",
    temperature = 1.0,
    max_tokens = 2048,
    top_p = 1.0,
    frequency_penalty = 0.0,
    presence_penalty = 0.0
)

# Afficher la réponse de l'assistant
println(response["choices"][1]["message"]["content"])
Creating a fully-featured Snake game in Julia can be quite an involved process since it requires handling game logic, rendering, and user input. Below is a simplified version of a text-based Snake game in Julia. This version uses basic console I/O to handle the game loop, snake movement, and food generation.

First, make sure you have Julia installed. You can create a new file, say `snake_game.jl`, and put the following code inside it:

```julia
using Random

# Game settings
const BOARD_WIDTH = 20
const BOARD_HEIGHT = 10
const INITIAL_SNAKE_LENGTH = 3
const REFRESH_RATE = 0.1

# Directions
const UP = (0, -1)
const DOWN = (0, 1)
const LEFT = (-1, 0)
const RIGHT = (1, 0)

# Game state
mutable struct GameState
    snake::Array{Tuple{Int, Int}, 1}
    direction::Tuple{Int, Int}
    food::Tuple{Int, Int}
    alive::Bool
end

function initialize_game()
    snake = [(BOARD_WIDTH ÷ 2, BOARD_HEIGHT ÷ 2)]
    for i in 1:INITIAL_SNAKE_LENGTH-1
        push!(snake, (BOARD_WIDTH ÷ 2 - i, BOARD_HEIGHT ÷ 2))
    end
    direction = RIGHT
    food = generate_food(snake)
    alive = true
    return GameState(snake, direction, food, alive)
end

function generate_food(snake)
    while true
        food = (rand(1:BOARD_WIDTH), rand(1:BOARD_HEIGHT))
        if food ∉ snake
            return food
        end
    end
end

function draw_game(state::GameState)
    println("\033[2J")  # Clear screen
    for y in 1:BOARD_HEIGHT
        for x in 1:BOARD_WIDTH
            if (x, y) in state.snake
                print("#")
            elseif (x, y) == state.food
                print("*")
            else
                print(".")
            end
        end
        println()
    end
end

function update_game!(state::GameState)
    head = state.snake[1]
    new_head = (head[1] + state.direction[1], head[2] + state.direction[2])

    if new_head in state.snake || new_head[1] < 1 || new_head[1] > BOARD_WIDTH || new_head[2] < 1 || new_head[2] > BOARD_HEIGHT
        state.alive = false
        return
    end

    pushfirst!(state.snake, new_head)

    if new_head == state.food
        state.food = generate_food(state.snake)
    else
        pop!(state.snake)
    end
end

function get_input()
    if isready(stdin)
        c = read(stdin, Char)
        if c == 'w'
            return UP
        elseif c == 's'
            return DOWN
        elseif c == 'a'
            return LEFT
        elseif c == 'd'
            return RIGHT
        end
    end
    return nothing
end

function run_game()
    state = initialize_game()

    while state.alive
        draw_game(state)
        new_direction = get_input()
        if new_direction != nothing && state.direction != (-new_direction[1], -new_direction[2])
            state.direction = new_direction
        end
        update_game!(state)
        sleep(REFRESH_RATE)
    end
    println("Game Over!")
end

run_game()
```

This code implements a simple Snake game where:

1. The snake starts in the middle of the board.
2. The snake moves in a direction (initially to the right).
3. Food is generated randomly on the board.
4. The snake grows when it eats the food.
5. The game ends when the snake hits itself or the walls.
6. The screen is updated at a fixed refresh rate.

To play the game, run the program and use the `w`, `a`, `s`, and `d` keys to control the snake's direction (up, left, down, and right, respectively).

To run the game, execute the script using the Julia interpreter:
```sh
julia snake_game.jl
```

This is a basic implementation with limited features. For more advanced versions (with graphics and better input handling), you might want to look into using libraries like SDL via the Julia `SDL.jl` package.
In [5]:
# Appeler la fonction pour obtenir une réponse
response = call_openai_api(
    messages;  # Required argument
    model = "gpt-4o-mini",
    temperature = 1.0,
    max_tokens = 2048,
    top_p = 1.0,
    frequency_penalty = 0.0,
    presence_penalty = 0.0
)

# Afficher la réponse de l'assistant
println(response["choices"][1]["message"]["content"])
Creating a basic Snake game in Julia can be a fun project! Below is a simple implementation using the `Gtk.jl` package for graphical interface and `Random` module for generating the food. Ensure you have the `Gtk.jl` package installed using the Julia package manager.

You can run the following code to create a simple Snake game:

```julia
using Gtk
using Random

# Constants
const WIDTH = 400
const HEIGHT = 400
const TILE_SIZE = 20
const INITIAL_LENGTH = 3

# Directions
const UP = (0, -1)
const DOWN = (0, 1)
const LEFT = (-1, 0)
const RIGHT = (1, 0)

struct SnakeGame
    window::Gtk.Window
    canvas::Gtk.DrawingArea
    snake::Array{Tuple{Int, Int}, 1}
    direction::Tuple{Int, Int}
    food::Tuple{Int, Int}
    score::Int
    timer::Gtk.Timeout
end

function create_food(snake::Array{Tuple{Int, Int}, 1})
    while true
        food = (rand(0:WIDTH÷TILE_SIZE - 1), rand(0:HEIGHT÷TILE_SIZE - 1))
        if !(food in snake)
            return food
        end
    end
end

function init_game()
    snake = [(i, 0) for i in INITIAL_LENGTH - 1:-1:0]
    direction = RIGHT
    food = create_food(snake)
    score = 0

    return SnakeGame(Gtk.Window("Snake Game", WIDTH, HEIGHT), Gtk.DrawingArea(), snake, direction, food, score, nothing)
end

function draw_snake(c::Gtk.DrawingArea, game::SnakeGame)
    Gtk.set_gtk_property!(game.canvas, :bgcolor, "white")
    for (x, y) in game.snake
        Gtk.draw_rectangle(c, Gtk.Gdk.RGBA(0, 1, 0, 1), true, x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE)
    end
    
    # Draw food
    x, y = game.food
    Gtk.draw_rectangle(c, Gtk.Gdk.RGBA(1, 0, 0, 1), true, x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE)

    # Draw score
    Gtk.set_gtk_property!(game.window, :title, "Snake Game - Score: $(game.score)")
end

function game_tick(game::SnakeGame)
    head = game.snake[1]
    new_head = (head[1] + game.direction[1], head[2] + game.direction[2])
    
    # Game over conditions
    if new_head in game.snake || new_head[1] < 0 || new_head[1] >= WIDTH÷TILE_SIZE || new_head[2] < 0 || new_head[2] >= HEIGHT÷TILE_SIZE
        Gtk.Gdk.set_window_decorated(Gtk.widget_get_window(game.window), false)
        println("Game Over! Final Score: $(game.score)")
        Gtk.Gtk.main_quit()
        return
    end

    # Update snake
    push!(game.snake, new_head)
    if new_head == game.food
        game.score += 1
        game.food = create_food(game.snake)
    else
        pop!(game.snake)
    end

    # Redraw
    draw_snake(game.canvas, game)

    # Continue the timer
    return true
end

function on_key_press(widget, event, game::SnakeGame)
    if event.keyval == Gtk.GDK.KEY_Up && game.direction != DOWN
        game.direction = UP
    elseif event.keyval == Gtk.GDK.KEY_Down && game.direction != UP
        game.direction = DOWN
    elseif event.keyval == Gtk.GDK.KEY_Left && game.direction != RIGHT
        game.direction = LEFT
    elseif event.keyval == Gtk.GDK.KEY_Right && game.direction != LEFT
        game.direction = RIGHT
    end
end

function run_game()
    game = init_game()
    push!(game.window, game.canvas)
    Gtk.resize(game.canvas, WIDTH, HEIGHT)
    
    signal_connect(game.canvas, "draw") do widget
        draw_snake(widget, game)
    end
    
    # Timer for game tick
    game.timer = Gtk.@timeout(150) do
        game_tick(game)
    end

    signal_connect(game.window, "destroy") do widget
        Gtk.Gtk.main_quit()
    end
    signal_connect(game.window, "key-press-event") do widget, event
        on_key_press(widget, event, game)
    end

    showall(game.window)
    Gtk.Gtk.main()
end

run_game()
```

### Instructions to Run the Game

1. Make sure you have Julia installed on your machine.
2. Install the `Gtk.jl` package if you have not already:

   ```julia
   using Pkg
   Pkg.add("Gtk")
   ```

3. Copy the code above into a file named `snake_game.jl`.
4. Open a terminal or command prompt.
5. Run the game with the command:

   ```bash
   julia snake_game.jl
   ```

### Controls

- Use the arrow keys to control the direction of the snake.
- The game ends if the snake collides with itself or the wall.

This is a simple implementation and can be further enhanced with more features (like levels, score saving, etc.), sound effects, and graphics. Enjoy coding!
In [6]:
# Appeler la fonction pour obtenir une réponse
response = call_openai_api(
    messages;  # Required argument
    model = "gpt-4-turbo",
    temperature = 1.0,
    max_tokens = 2048,
    top_p = 1.0,
    frequency_penalty = 0.0,
    presence_penalty = 0.0
)

# Afficher la réponse de l'assistant
println(response["choices"][1]["message"]["content"])
Creating a Snake game in Julia involves using graphical libraries such as `Gtk.jl` or creating text-based games in the console. Below, I will provide a basic structure for a console-based Snake game in Julia using simple data structures and basic I/O. This version keeps the game quite simple and minimalistic.

First, make sure you have Julia installed on your computer. You can download it from [the official Julia programming language site](https://julialang.org/downloads/).

Here's a simple text-based version of the Snake game in Julia:

```julia
using Base.Iterators: cycle

const S_RIGHT, S_LEFT, S_UP, S_DOWN = 1, 2, 3, 4
const WIDTH, HEIGHT = 30, 15
const FRAMETIME = 0.1

mutable struct GameState
    snake
    direction::Int
    food::Tuple{Int, Int}
    score::Int
    game_over::Bool
end

function init_game()
    snake = [(10, 5), (10, 4), (10, 3)]
    direction = S_RIGHT
    food = (rand(1:WIDTH), rand(1:HEIGHT))
    GameState(snake, direction, food, 0, false)
end

function print_game(state::GameState)
    cls()
    for y in 1:HEIGHT
        for x in 1:WIDTH
            if (x, y) in state.snake
                print("#")
            elseif (x, y) == state.food
                print("*")
            else
                print(" ")
            end
        end
        println()
    end
    println("Score: ", state.score)
    if state.game_over
        println("Game Over!")
    end
end

function cls()
    print("\x1B[2J")
end

function wrap(pos, max)
    pos < 1 && return max
    pos > max && return 1
    return pos
end

function move_snake(state::GameState)
    head = state.snake[1]
    new_head = (0, 0)
    if state.direction == S_RIGHT
        new_head = (wrap(head[1] + 1, WIDTH), head[2])
    elseif state.direction == S_LEFT
        new_head = (wrap(head[1] - 1, WIDTH), head[2])
    elseif state.direction == S_UP
        new_head = (head[1], wrap(head[2] - 1, HEIGHT))
    elseif state.direction == S_DOWN
        new_head = (head[1], wrap(head[2] + 1, HEIGHT))
    end

    if new_head in state.snake
        state.game_over = true
    end

    unshift!(state.snake, new_head)

    if new_head == state.food
        state.score += 1
        state.food = (rand(1:WIDTH), rand(1:HEIGHT))
    else
        pop!(state.snake)
    end
end

function play_game()
    state = init_game()
    while !state.game_over
        print_game(state)
        sleep(FRAMETIME)
        if !isempty(readavailable(stdin, String))
            c = read(stdin, Char)
            if c == 'w' && state.direction != S_DOWN
                state.direction = S_UP
            elseif c == 's' && state.direction != S_UP
                state.direction = S_DOWN
            elseif c == 'a' && state.direction != S_RIGHT
                state.direction = S_LEFT
            elseif c == 'd' && state.direction != S_LEFT
                state.direction = S_RIGHT
            end
        end
        move_snake(state)
    end
    print_game(state)
end

# Uncomment below line to run the game.
# play_game()
```

This example provides a very basic implementation of the Snake game in the console. The snake can be controlled with the 'w', 'a', 's', 'd' keys representing up, left, down, and right respectively. You need to set the terminal to non-blocking or raw mode to read keystrokes. In standard Julia REPL or scripts mode, input can be buffered and will not behave as expected in interactive games. Use terminal-specific libraries or other tools to capture key inputs in real-time if required.
In [7]:
# Appeler la fonction pour obtenir une réponse
response = call_openai_api(
    messages;  # Required argument
    model = "gpt-3.5-turbo",
    temperature = 1.0,
    max_tokens = 2048,
    top_p = 1.0,
    frequency_penalty = 0.0,
    presence_penalty = 0.0
)

# Afficher la réponse de l'assistant
println(response["choices"][1]["message"]["content"])
Sure! Below is a simple implementation of the classic Snake Game in Julia using the Luxor package for graphics:

```julia
using Luxor

const N = 20
const SIZE=32
const SPEED = 0.1

direction = :right
snake = [(N ÷ 2, N ÷ 2)]
food = (rand(1:N), rand(1:N))

function draw_snake()
    sethue("green")
    for segment in snake
        square(segment[1], segment[2], SIZE, :fill)
    end
end

function draw_food()
    sethue("red")
    square(food[1], food[2], SIZE, :fill)
end

function check_collision()
    head = snake[1]
    if head[1] < 1 || head[2] < 1 || head[1] > N || head[2] > N
        return true
    end
    for i in 2:length(snake)
        if head == snake[i]
            return true
        end
    end
    return false
end

function move_snake()
    head = snake[1]
    new_head = head
    if direction == :right
        new_head = (head[1] + 1, head[2])
    elseif direction == :left
        new_head = (head[1] - 1, head[2])
    elseif direction == :up
        new_head = (head[1], head[2] - 1)
    elseif direction == :down
        new_head = (head[1], head[2] + 1)
    end
    insert!(snake, 1, new_head)
    if new_head != food
        pop!(snake)
    else
        food = (rand(1:N), rand(1:N))
    end
end

function play_game()
    while true
        if check_collision()
            break
        end
        background("lightgrey")
        draw_food()
        draw_snake()
        sleep(SPEED)
        move_snake()
        Luxor.display()
    end
    text("Game Over", hcenter=true, vcenter=true, point=N÷2, size=50)
    Luxor.display()
end

function key_handler(key)
    global direction
    if key == Luxor.RIGHT_KEY
        direction = :right
    elseif key == Luxor.LEFT_KEY
        direction = :left
    elseif key == Luxor.UP_KEY
        direction = :up
    elseif key == Luxor.DOWN_KEY
        direction = :down
    end
end

@svg begin
    setline(2)
    playsvg(play_game, keypress_handler=key_handler)
end
```

You will need to install the Luxor package by running `] add Luxor` in the Julia REPL before running this code. Let me know if you need any further assistance!