π
<-

Concours de rentrée 2020 - défi Python du Léviathan

Re: Concours de rentrée 2020 - défi Python du Léviathan

Unread postby critor » 07 Nov 2020, 16:27

Nouvelle participation du n°2. Evaluation en direct dès maintenant, voyons si il arrive à se dépasser : ;)
https://tiplanet.org/concours_rentree20 ... &invalid=1
Image
User avatar
critorAdmin
Niveau 19: CU (Créateur Universel)
Niveau 19: CU (Créateur Universel)
Level up: 47.5%
 
Posts: 41980
Images: 15737
Joined: 25 Oct 2008, 00:00
Location: Montpellier
Gender: Male
Calculator(s):
MyCalcs profile
YouTube: critor3000
Twitter: critor2000
GitHub: critor

Re: Concours de rentrée 2020 - défi Python du Léviathan

Unread postby critor » 07 Nov 2020, 17:38

Non pas une, mais 2 nouvelles IA par le participant n°10.

Evaluation retransmise en direct dès maintenant : ;)
https://tiplanet.org/concours_rentree20 ... &invalid=1
Image
User avatar
critorAdmin
Niveau 19: CU (Créateur Universel)
Niveau 19: CU (Créateur Universel)
Level up: 47.5%
 
Posts: 41980
Images: 15737
Joined: 25 Oct 2008, 00:00
Location: Montpellier
Gender: Male
Calculator(s):
MyCalcs profile
YouTube: critor3000
Twitter: critor2000
GitHub: critor

Re: Concours de rentrée 2020 - défi Python du Léviathan

Unread postby Fime » 07 Nov 2020, 18:46

Image
(la porte est à la même corniche que le leviathan)
Il m'est arrivé plusieurs situations de ce type, est-ce prévu ?
User avatar
Fime
Niveau 5: MO (Membre Overclocké)
Niveau 5: MO (Membre Overclocké)
Level up: 0%
 
Posts: 12
Joined: 05 Nov 2020, 19:35
Location: Lyon - France
Gender: Male
Calculator(s):
MyCalcs profile
Class: INSA Lyon promo 67
GitHub: fime-space

Re: Concours de rentrée 2020 - défi Python du Léviathan

Unread postby critor » 07 Nov 2020, 18:49

Oui, puisque tu peux tuer le Léviathan.
Quand tu es à côté, c'est return corniche_leviathan, 1 pour tirer ton unique flèche.

Si tu as bien visé son affichage passe en gris, et tu peux alors aller sur sa corniche sans danger. :)
Image
User avatar
critorAdmin
Niveau 19: CU (Créateur Universel)
Niveau 19: CU (Créateur Universel)
Level up: 47.5%
 
Posts: 41980
Images: 15737
Joined: 25 Oct 2008, 00:00
Location: Montpellier
Gender: Male
Calculator(s):
MyCalcs profile
YouTube: critor3000
Twitter: critor2000
GitHub: critor

Re: Concours de rentrée 2020 - défi Python du Léviathan

Unread postby Fime » 07 Nov 2020, 18:56

critor wrote:Oui, puisque tu peux tuer le Léviathan.
Quand tu es à côté, c'est return corniche_leviathan, 1 pour tirer ton unique flèche.

Si tu as bien visé son affichage passe en gris, et tu peux alors aller sur sa corniche sans danger. :)

Attends, on est d'accord que corniche_leviathan est une variable que l'on créer pour se faciliter la vie, qui n'est pas fournie par defaut ?
User avatar
Fime
Niveau 5: MO (Membre Overclocké)
Niveau 5: MO (Membre Overclocké)
Level up: 0%
 
Posts: 12
Joined: 05 Nov 2020, 19:35
Location: Lyon - France
Gender: Male
Calculator(s):
MyCalcs profile
Class: INSA Lyon promo 67
GitHub: fime-space

Re: Concours de rentrée 2020 - défi Python du Léviathan

Unread postby critor » 07 Nov 2020, 18:58

C'est le numéro de sa corniche, bien évidemment inconnu.

A toi de le deviner/déduire, si bien sûr tu en as besoin.

Il n'y a aucun bonus de score pour avoir tué le Léviathan.
Image
User avatar
critorAdmin
Niveau 19: CU (Créateur Universel)
Niveau 19: CU (Créateur Universel)
Level up: 47.5%
 
Posts: 41980
Images: 15737
Joined: 25 Oct 2008, 00:00
Location: Montpellier
Gender: Male
Calculator(s):
MyCalcs profile
YouTube: critor3000
Twitter: critor2000
GitHub: critor

Re: Concours de rentrée 2020 - défi Python du Léviathan

Unread postby Afyu » 07 Nov 2020, 19:01

cent20 wrote:J'ai envoyé ma première participation mais je suis à l'aveugle complet faute de réussir à boucler l'évaluation.
Afyu tu nous fais un tuto sur linux, en expliquant pas à pas comment tu fais pour tester un script 1000 fois ?

C'est parti !

Les deux scripts proposés juste après sont simplement ceux proposés par critor dans les commentaires. Merci à lui ! :)

On crée un fichier web.py qui contient :
Code: Select all
#cas
from math import pi, cos, sin, floor
import sys

#---
# RNG

rnd_seed = int(sys.argv[1]) if len(sys.argv) > 1 else 0xc0ffee
web_dim = int(sys.argv[2]) if len(sys.argv) > 2 else 36
web_density = float(sys.argv[3]) if len(sys.argv) > 3 else .05
pits_density = float(sys.argv[4]) if len(sys.argv) > 4 else .1
bats_density = float(sys.argv[5]) if len(sys.argv) > 5 else .15

def rnd():
  global rnd_seed
  rnd_max = 0x7fff
  rnd_seed = (rnd_seed * 214013 + 2531011) % 4294967296
  return ((rnd_seed // (2*rnd_max + 1)) & rnd_max)

def random():
  return rnd() / 0x7fff

def randint(a,b):
  return rnd() % (b-a+1) + a

def choice(l):
  return l[randint(0, len(l)-1)]

#---


screen_h = 240
m_p, m_l, m_k, m_b, m_d, m_a, m_m = 1, 4, 16, 64, 256, 1024, 4096

def insertinto(l1, l2):
  for v in l1:
    if v not in l2:
      l2.append(v)
  return l2

def removefrom(l1, l2):
  for v in l1:
    try:
      l2.remove(v)
    except:
      pass
  return l2

def connectPlatforms(s1, s2):
  global web
  web[s1][s2], web[s2][s1] = 1, 1

def get_reachable_platforms_from_platforms(l, safe):
  lv = []
  for s in l:
    for i in range(dimweb):
      if web[s][i]:
        if i not in lv and (not(safe) or not (platforms[i] & m_p)):
          lv.append(i)
  return lv

def cango(s1, s2, safe):
  lvo1, lvi1, lvo2, lvi2, t_inter, k = [], [s1], [], [s2], 0, 0
  while not (t_inter) and len(lvi1) and len(lvi2):
    lvo1, lvo2 = insertinto(lvo1, lvi1), insertinto(lvo2, lvi2)
    for v in lvo1:
      if v in lvo2:
        return k
    lvi1, lvi2 = get_reachable_platforms_from_platforms(lvo1, safe), get_reachable_platforms_from_platforms(lvo2, safe)
    lvi1, lvi2 = removefrom(lvo1, lvi1), removefrom(lvo2, lvi2)
    k += 1
  return 0

def my_bitor(a, b):
  return ~(~a & ~b)

def init_web(d, p_p, p_b):
  global web, platforms, mwspr, mhspr, zoom, mwc, screen_w, screen_h
  yweb, l0 = screen_h / 2, list(range(dimweb))
  l0.remove(0)
  web, platforms, conn, dconn, i_k = [], [0 for k in range(dimweb)], [0], list(range(1, dimweb)), choice(l0)
  for j in range(dimweb):
    web.append([0 for k in range(dimweb)])
  while len(dconn):
    s = dconn[randint(0, len(dconn) - 1)]
    connectPlatforms(conn[randint(0, len(conn) - 1)], s)
    dconn.remove(s)
    conn.append(s)
  for j in range(dimweb-1):
    for i in range(j + 1, dimweb):
      if floor(d + random()):
        connectPlatforms(i, j)
  i_d = choice(l0)
  platforms[i_d] = my_bitor(platforms[i_d], m_d)
  l1 = list(l0)
  for v in get_reachable_platforms_from_platforms([0], 0):
    l1.remove(v)
  if not(len(l1)):
    l1 = l0
  l2 = list(l1)
  for v in get_reachable_platforms_from_platforms(get_reachable_platforms_from_platforms([0], 0), 0):
    try:
      l2.remove(v)
    except:
      pass
  if not(len(l2)):
    l2 = l1
  i_l = choice(l2)
  platforms[i_l] = my_bitor(platforms[i_l], m_l)
  platforms[i_k] = my_bitor(platforms[i_k], m_k)
  for i in l1:
    if i != i_k and i != i_d and floor(p_p*dimweb/len(l1) + random()):
      if cango(0, i_k, 1) and cango(0, i_d, 1):
        platforms[i] = my_bitor(platforms[i], m_p)
    if floor(p_b*dimweb/len(l1) + random()):
      platforms[i] = my_bitor(platforms[i], m_b)

def parcourir_selon(ia):
  global dimweb, platforms, web_dim, web_density, pits_density, bats_density
  dimweb = web_dim
  maxcoups = dimweb**2 * 2
  init_web(web_density, pits_density, bats_density)

  s0, s1, s2, s3, s4, s5, s6, s7 = 0, 0, m_a, 0, 1, -1, 0, 0
  pfs0, pfs5 = platforms[s0], 0
  while s4 > 0  and (not (s2 & (2 * m_k)) or not (pfs0 & m_d)):
    if s5 < 0:
      s5 = 0
    else:
      try:
        k, k2 = ia(s0, voisines, dimweb, s1, s2)
        if pfs5 & (2 * m_b):
          while s0 == s5:
            s0 = randint(0, dimweb - 1)
          pfs0, pfs5 = my_bitor(platforms[s0], m_b), pfs5 & ~(3 * m_b) & ~m_m
        else:
          if k2:
            if s2 & m_a:
              v = platforms[k]
              if v & m_l:
                v, s2 = v & ~m_l, my_bitor(s2, 2 * m_l)
                platforms[k] = my_bitor(v, 2 * m_l)
              s2 = s2 & ~m_a
              s2 = my_bitor(s2, 2 * m_a)
          else:
            if k in voisines:
              s0 = k
              if pfs5 & m_b:
                pfs5 = my_bitor(pfs5, 2 * m_b)
              pfs0, pfs5 = platforms[s0], pfs5 & ~m_m
          s3 += 1
          if s3 >= maxcoups:
            s4 = 0
        if pfs0 & m_k:
          pfs0 = pfs0 & ~m_k
          s2 = my_bitor(s2, 2 * m_k)
        if pfs0 & my_bitor(m_p, m_l):
          s4 = 0
          pfs0 = my_bitor(pfs0, 2 * m_m)
        platforms[s5] = pfs5
      except Exception as t_excpt:
        s4 = -1
        print(t_excpt)
    pfs0 = my_bitor(pfs0, m_m)
    s1, voisines = pfs0, get_reachable_platforms_from_platforms([s0], 0)
    platforms[s0] = pfs0
    for v in voisines:
      t = my_bitor(m_p, m_l)
      t = platforms[v] & my_bitor(t, m_k)
      s1 = my_bitor(s1, t)
    for v in get_reachable_platforms_from_platforms(voisines, 0):
      t = platforms[v] & m_l
      s1 = my_bitor(s1, t)
    s, sold = my_bitor(s1, s2), my_bitor(s6, s7)
    s5, s6, s7, pfs5 = s0, s1, s2, pfs0
  r = s4 > 0 and s3 < maxcoups
  if r:
    print("win " + str(s3), file=sys.stderr)
  else:
    if pfs0 & m_l:
      print("leviathan", file=sys.stderr)
    elif pfs0 & m_p:
      print("well", file=sys.stderr)
    elif s3 >= maxcoups:
      print("lowpower", file=sys.stderr)
    elif s4 < 0:
      print("exception", file=sys.stderr)
  return r, s2, s3

Globalement c'est le script web.py fourni pour le concours mais dont on a retiré tout ce qui est affichage graphique. Attention au respect de l'indentation quand on fait son copier-coller.

Ensuite, on crée un fichier bash que l'on nomme comme on veut (disons eval.sh) et qui contient :
Code: Select all
#! /bin/bash

if [[ ! "$2" ]]; then
  echo "usage: $0 <nb of simulations> <l?.py file num>" >&2
  exit 1
fi

base_file="l""$2"
script_file="$base_file"".py"
infos_file="$base_file"".txt"
timestamp="$(date +"%s")"
# First seed for the tests
base_seed="$2"
# Web size for the tests
web_size=36
# Web density for the tests
web_density=.05
# Pits density for the tests
pits_density=.1
# Bats density for the tests
bats_density=.15
# Number of tests
test_count="$1"
# Total time spent escaping
escape_time=0
# Number of successful escapes, falls in wells, leviathan mishaps, exceptions
escapes=0
well=0
leviathan=0
exception=0
lowpower=0

RANDOM=$base_seed

# Upper bound is the number of tests
for i in $(seq 1 $test_count); do
  percent=$(echo "scale=2; $i*100/$test_count" | bc)
#  echo -ne "\rseed: $i/$test_count ($percent%)..." >&2
  result=$(python3 "$script_file" $RANDOM $web_size $web_density $pits_density $bats_density 2>&1 >/dev/null)

  case "$result" in
    "win "*)
      escape_time=$(($escape_time+${result#* }))
      escapes=$(($escapes+1));;
    "well")
      well=$(($well+1));;
    "leviathan")
      leviathan=$(($leviathan+1));;
    "lowpower")
      lowpower=$(($lowpower+1));;
    "exception")
      exception=$(($exception+1));;
  esac
  cat <<EOF > "$infos_file"
  $timestamp #date
  $test_count #total simulations
  $i #simulations
  $base_seed #seed
  $web_size #web size
  $web_density #web density
  $pits_density #pits density
  $bats_density #bats density
  $escapes #successes
  $escape_time #successes total steps
  $leviathan #fails by Leviathan
  $well #fails by well
  $lowpower #fails by low power
  $exception #fails by exception
EOF
done

printf "\r%40s\r" "" >&2

Ce script eval.sh doit être exécutable. Pour ça, on peut taper la ligne de commande suivante :
Code: Select all
$ sudo chmod a+x eval.sh


Ensuite, on met son IA dans un fichier webtest.py (comme c'est demandé pour le concours, on peut par exemple reprendre le webtest.py prévu pour l'IDE Omega, dans les ressources NumWorks).

On renomme le fichier webtest.py en l1.py et pour tester cette IA 1000 fois, on tape, dans une console Linux ouverte dans le dossier qui contient nos 3 scripts :
Code: Select all
$ ./eval.sh 1000 1
ou bien
Code: Select all
$ source ./eval.sh 1000 1

(On peut également ouvrir une console, puis se déplacer jusqu'au dossier qui contient les 3 scripts avec
Code: Select all
$ cd /chemin/vers/mon/dossier
juste avant de lancer la commande qui lance les 1000 tests)

Dans cette ligne de commande, eval.sh est le script de test, 1000 est le nombre de tests que l'on souhaite effectuer et 1 est transformé en l1.py lors de l'exécution de eval.sh et ça va exécuter le script l1.py 1000 fois. En remplaçant 1 par 2 on exécute le script l2.py 1000 fois et en remplaçant 1000 par 100000 on lance l'exécution 100 000 fois plutôt que 1000 fois.

Le résultat des 1000 simulations est stocké dans le fichier l1.txt qui est alors créé dans le même dossier.

Remarque 1 :
Si on veut utiliser autre chose que "python3" comme lanceur python, alors dans le script eval.sh il faut remplacer "python3" par ce que l'on souhaite.

Remarque 2 :
Le script polycal3.py n'est pas nécessaire puisqu'il n'y a pas d'affichage graphique.

Remarque 3 :
Si on veut un affichage comme dans les scripts du concours, alors il vaut mieux se tourner vers le script proposé par LeGmask dans les commentaires, mais en oubliant l'idée de lancer une simulation de 1000 exécutions (et en prenant garde au fait qu'il demande 2 arguments dans "parcourir_selon(ia,N)").

Remarque 4 :
Dans le fichier eval.sh ce sont les lignes
Code: Select all
base_file="l""$2"
script_file="$base_file"".py"
infos_file="$base_file"".txt"
qui créent une variable base_file qui contient "l1" si on a mis "1" comme dernier argument dans la ligne de commande lançant les 1000 tests, une variable script_file qui contient "l1.py" et une variable infos_file qui contient "l1.txt". On peut adapter ces trois lignes si l'on veut par exemple mettre comme argument (dans la ligne de commande qui lance les 1000 simulations) son nom de fichier complet et pas uniquement un "1" pour "l1.py", un "2" pour "l2.py" et ainsi de suite... On pourrait alors remplacer ces 3 lignes par :
Code: Select all
script_file="$2"
infos_file="$2"".txt"
Mais attention, la graine qui initialise le générateur de nombres aléatoires est précisément le 2ème argument passé dans la ligne de commande. Il faut alors passer un nombre en 3ème argument et remplacer la ligne
Code: Select all
base_seed="$2"
par
Code: Select all
base_seed="$3"
pour être sûr d'initialiser le générateur de nombres aléatoires sans avoir d'erreur.
La commande pour lancer une simulation de 3000 exécutions de son script webtest.py avec le nombre 42 pour initialiser le générateur de nombres aléatoires, devient alors :
Code: Select all
$ ./eval.sh 3000 ./webtest.py 42
ou bien
Code: Select all
$ source ./eval.sh 3000 ./webtest.py 42
et le résultat des 3000 simulations est alors stocké dans le fichier webtest.py.txt créé automatiquement.

J'ai mis les fichiers web.py et eval.sh (il s'appelle eval.txt et il faut le renommer) en pièces jointes.

J'espère n'avoir rien oublié. Si un passage n'est pas clair ou pas suffisamment développé, dites-le moi ! :D

Bonne chance !
You do not have the required permissions to view the files attached to this post.
Last edited by Afyu on 07 Nov 2020, 22:37, edited 8 times in total.
User avatar
AfyuVIP++
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Level up: 2.7%
 
Posts: 405
Images: 149
Joined: 30 Oct 2019, 19:17
Gender: Male
Calculator(s):
MyCalcs profile
Class: plutôt, oui :)

Re: Concours de rentrée 2020 - défi Python du Léviathan

Unread postby critor » 07 Nov 2020, 19:49

Merci @Afyu, c'est sympa de ta part. :)
Image
User avatar
critorAdmin
Niveau 19: CU (Créateur Universel)
Niveau 19: CU (Créateur Universel)
Level up: 47.5%
 
Posts: 41980
Images: 15737
Joined: 25 Oct 2008, 00:00
Location: Montpellier
Gender: Male
Calculator(s):
MyCalcs profile
YouTube: critor3000
Twitter: critor2000
GitHub: critor

Re: Concours de rentrée 2020 - défi Python du Léviathan

Unread postby Afyu » 07 Nov 2020, 19:53

critor wrote:Merci @Afyu, c'est sympa de ta part. :)

J'espère que ça pourra aider. J'espère surtout n'avoir rien oublié et ne pas m'être trompé...
Dites-moi si ça fonctionne ! :)
User avatar
AfyuVIP++
Niveau 16: CC2 (Commandeur des Calculatrices)
Niveau 16: CC2 (Commandeur des Calculatrices)
Level up: 2.7%
 
Posts: 405
Images: 149
Joined: 30 Oct 2019, 19:17
Gender: Male
Calculator(s):
MyCalcs profile
Class: plutôt, oui :)

Re: Concours de rentrée 2020 - défi Python du Léviathan

Unread postby critor » 07 Nov 2020, 19:54

Nouvel essai du n°3, à suivre en direct :
https://tiplanet.org/concours_rentree20 ... &invalid=1
Image
User avatar
critorAdmin
Niveau 19: CU (Créateur Universel)
Niveau 19: CU (Créateur Universel)
Level up: 47.5%
 
Posts: 41980
Images: 15737
Joined: 25 Oct 2008, 00:00
Location: Montpellier
Gender: Male
Calculator(s):
MyCalcs profile
YouTube: critor3000
Twitter: critor2000
GitHub: critor

PreviousNext

Return to News Divers

Who is online

Users browsing this forum: ClaudeBot [spider] and 14 guests

-
Search
-
Social TI-Planet
-
Featured topics
Comparaisons des meilleurs prix pour acheter sa calculatrice !
"1 calculatrice pour tous", le programme solidaire de Texas Instruments. Reçois gratuitement et sans aucune obligation d'achat, 5 calculatrices couleur programmables en Python à donner aux élèves les plus nécessiteux de ton lycée. Tu peux recevoir au choix 5 TI-82 Advanced Edition Python ou bien 5 TI-83 Premium CE Edition Python.
Enseignant(e), reçois gratuitement 1 exemplaire de test de la TI-82 Advanced Edition Python. À demander d'ici le 31 décembre 2024.
Aidez la communauté à documenter les révisions matérielles en listant vos calculatrices graphiques !
1234
-
Donations / Premium
For more contests, prizes, reviews, helping us pay the server and domains...
Donate
Discover the the advantages of a donor account !
JoinRejoignez the donors and/or premium!les donateurs et/ou premium !


Partner and ad
Notre partenaire Jarrety Calculatrices à acheter chez Calcuso
-
Stats.
803 utilisateurs:
>757 invités
>37 membres
>9 robots
Record simultané (sur 6 mois):
6892 utilisateurs (le 07/06/2017)
-
Other interesting websites
Texas Instruments Education
Global | France
 (English / Français)
Banque de programmes TI
ticalc.org
 (English)
La communauté TI-82
tout82.free.fr
 (Français)