Beta

Duel Snakes Overview

Duel Snakes has the same mechanics as Snake, but your algo competes against another to see who can survive the longest. The snake left alive wins. If both die on the same tick, or the board fills up with both still alive, the snake that ate more apples wins, and the same number of apples is a draw. There are also five apples on the board at all times instead of one.

Details

Time per move 50 milliseconds: the engine plays a tick every 50 milliseconds, with the last move each algo sent, and state.time_left says how much of the tick is left. (We are still figuring out the best amount of time to provide for our games. This is subject to change.)
Ranking system Each ranked version has a strength, worked out from every ranked match of Duel Snakes ever played: who beat whom, with a draw counting as half a win each. The gap between two strengths is the odds of one beating the other: equal strengths are an even match, a gap of 1 is about 73% to the stronger, and a gap of 2 about 88%. Zero is the average of the versions the leaderboard was last updated for: those set to Ranked at the time that had played a ranked match. So a strength above zero is better than the average of them. The leaderboard is ordered by strength, and its Uncertainty column says how far off a strength may still be; it shrinks as the version plays. A newly ranked version is in trials until its uncertainty is 0.5 or less: its ranked matches are played and you can see its numbers under My Algos, but it has no place on the leaderboard yet. That takes about fourteen close matches, and more if they are one-sided. Ranked matches go to the pairs that would teach the most: two versions of similar strength, at least one of them still uncertain. So a new version plays a lot at first, against opponents closer and closer to its own strength. A version's code never changes, so every ranked match it has ever played counts, even if you take it out of ranking and put it back.
setup(start_pos) start_pos is a numpy array of the (row, column) coordinates of your starting position. This will be either [12, 2] or [12, 23].
Valid moves 0, 1, 2, or 3 which correspond to north, east, south, and west respectively.
## Sample Algo

This is the starter algo the local app fills a seat with, so it is the same code you can run and edit.

from algogames import DuelSnakesInterface

# Without a class there is no `self` to hang onto, so anything an algo wants to
# remember between updates is a module variable, written with `global`.
turn_num = -1
my_start_pos = None


def setup(start_pos):
    global my_start_pos
    my_start_pos = start_pos


def on_update(state):
    global turn_num
    turn_num += 1

    DuelSnakesInterface.log(f'snakes: {state.snakes}')
    if turn_num == 0:
        DuelSnakesInterface.log(f'started at: {my_start_pos}')
        DuelSnakesInterface.log(f'state: {state.snakes[0]}')

    _go_towards_apple(state)


def _go_towards_apple(state):
    # Seat 0 is always your own snake, whichever seat you are playing.
    snake = state.snakes[0]
    head = snake[0]
    direction = state.directions[0]
    DuelSnakesInterface.log(state.apples)
    apple = state.apples[0]

    if head[0] < apple[0]:
        if direction == DuelSnakesInterface.N:
            DuelSnakesInterface.set_direction(DuelSnakesInterface.E)
        else:
            DuelSnakesInterface.set_direction(DuelSnakesInterface.S)
    elif head[0] > apple[0]:
        if direction == DuelSnakesInterface.S:
            DuelSnakesInterface.set_direction(DuelSnakesInterface.E)
        else:
            DuelSnakesInterface.set_direction(DuelSnakesInterface.N)
    elif head[1] < apple[1]:
        if direction == DuelSnakesInterface.W:
            DuelSnakesInterface.set_direction(DuelSnakesInterface.N)
        else:
            DuelSnakesInterface.set_direction(DuelSnakesInterface.E)
    elif head[1] > apple[1]:
        if direction == DuelSnakesInterface.E:
            DuelSnakesInterface.set_direction(DuelSnakesInterface.N)
        else:
            DuelSnakesInterface.set_direction(DuelSnakesInterface.W)