one of the last commit

This commit is contained in:
2026-04-26 23:51:55 +02:00
parent edc421996f
commit 46d24f5367
3 changed files with 437 additions and 9 deletions

118
README.md
View File

@@ -1,12 +1,118 @@
# cowsay # cowsay
cowsay project for school Projet INF203 autour de `cowsay`.
Cette même README est aussi publiée sur le site : <https://docs.fare-elouan.net/cowsay>, Les graphisme pour la charte seront mieux
il y a aussi le depot sur <https://git.fare-elouan.net/school/cowsay>
# Preliminaries ## Contenu du dépôt
cowsay options : - `start.sh` : lance un tour guidé de la plupart des programmes du projet.
- `ProjetCowsay.pdf` : document de projet au format PDF.
- `TODO.md` : checklist de suivi du travail demandé.
- `src/bash_scripts/` : scripts Bash.
- `src/C/` : programmes C principaux.
- `src/C/newcows/` : variantes C supplémentaires et script de compilation rapide.
- -e/--eyes ## Dépendances
- -T
-
Pour exécuter tout le projet, il faut au minimum :
- `bash`
- `cowsay`
- `bc` pour `smart_cow.sh`
- un compilateur C : `cc`, `clang` ou `gcc`
## Lancement rapide
Depuis la racine du dépôt :
```bash
bash start.sh
```
Le script de démonstration compile les programmes C dans un dossier temporaire puis exécute les différents exemples les uns après les autres.
## Résumé des scripts Bash
| Programme | Rôle | Exemple |
| --- | --- | --- |
| `cow_kindergarten.sh` | Fait parler la vache de `1` à `10`, avec une pause d'une seconde entre chaque valeur, puis termine avec une langue sortie. | `bash src/bash_scripts/cow_kindergarten.sh` |
| `cow_primaryschool.sh` | Fait parler la vache de `1` à `n`. | `bash src/bash_scripts/cow_primaryschool.sh 5` |
| `cow_highschool.sh` | Affiche les carrés parfaits de `1^2` à `n^2`. | `bash src/bash_scripts/cow_highschool.sh 5` |
| `cow_college.sh` | Affiche les `n` premiers termes de la suite de Fibonacci avec mémoïsation. | `bash src/bash_scripts/cow_college.sh 7` |
| `cow_university.sh` | Affiche les nombres premiers jusqu'à `n` avec un crible d'Ératosthène. | `bash src/bash_scripts/cow_university.sh 30` |
| `smart_cow.sh` | Évalue une expression arithmétique simple et essaie d'afficher le résultat dans les yeux de la vache. | `bash src/bash_scripts/smart_cow.sh '4+13'` |
| `crazy_cow.sh` | Génère une suite "look-and-say" de manière interactive, puis affiche toutes les étapes dans `cowsay`. | `bash src/bash_scripts/crazy_cow.sh` |
## Résumé des programmes C
| Programme | Rôle | Exemple |
| --- | --- | --- |
| `src/C/newcow.c` | Affiche une vache ASCII sans bulle, avec option `-e` ou `--eyes` pour changer les yeux. | `cc src/C/newcow.c -o /tmp/newcow && /tmp/newcow -e ^^` |
| `src/C/newcows/newcowT.c` | Variante de `newcow` qui gère la langue avec l'option `-T`. | `cc src/C/newcows/newcowT.c -o /tmp/newcowT && /tmp/newcowT -T U` |
| `src/C/newcows/newcowp.c` | Ajoute une bulle de texte simple au-dessus de la vache. | `cc src/C/newcows/newcowp.c -o /tmp/newcowp && /tmp/newcowp -p "Hello"` |
| `src/C/newcows/makefilealacon.sh` | Compile rapidement un fichier `.c` en un exécutable `.out` avec `clang`. | `bash src/C/newcows/makefilealacon.sh src/C/newcows/newcowT.c` |
| `src/C/newcow2.c` | Regroupe plusieurs animations terminales : clignement, langue, marche, rebond. | `cc src/C/newcow2.c -o /tmp/newcow2 && /tmp/newcow2 blink` |
| `src/C/reading_cow.c` | Lit un fichier caractère par caractère et montre la vache en train de "manger" le texte. | `cc src/C/reading_cow.c -o /tmp/reading_cow && /tmp/reading_cow --i 0.10 README.md` |
| `src/C/tamagoshi_cow.c` | Mini jeu en boucle avec gestion de `stock`, `fitness` et score de survie. | `cc src/C/tamagoshi_cow.c -o /tmp/tamagoshi_cow && /tmp/tamagoshi_cow` |
## Tour d'ensemble du projet
1. Bash simple avec comptage et pauses.
2. Bash plus algorithmique avec carrés, Fibonacci et nombres premiers.
3. Personnalisation de la vache en C.
4. Animations et interactions dans le terminal.
5. Programme de lecture de fichier.
6. Automate de jeu avec états pour le tamagotchi.
## Partie automate
- `liferocks` si `fitness` est entre `4` et `6`
- `lifesucks` si `fitness` est entre `1` et `3` ou entre `7` et `9`
- `byebyelife` si `fitness` vaut `0` ou `10`
À chaque tour :
- le joueur choisit `lunchfood`
- `fitness` est mise à jour avec un effet de digestion aléatoire
- `stock` est mis à jour avec une variation aléatoire de récolte
- si `fitness` atteint `0` ou `10`, la partie s'arrête
```flow
st=>start: Début du jeu
init=>operation: fitness = 5 ; stock = 5 ; score = 0
etat=>condition: fitness == 0 ou fitness == 10 ?
mort=>end: byebyelife Afficher score final
checkRock=>condition: 4 ≤ fitness ≤ 6 ?
liferocks=>operation: liferocks;Afficher vache saine
lifesucks=>operation: lifesucks;Afficher vache malade
affStock=>operation: Afficher stock
choix=>operation: lunchfood choisi;0 ≤ lunchfood ≤ stock
alea=>operation: digestion ∈ [-3,0];crop ∈ [-3,3]
majFit=>operation: fitness = fitness + lunchfood + digestion
clampFit=>operation: fitness borné entre 0 et 10
majStock=>operation: stock = stock - lunchfood + crop
clampStock=>operation: stock borné entre 0 et 10
score=>operation: score += 1
st->init->etat
etat(yes)->mort
etat(no)->checkRock
checkRock(yes)->liferocks->affStock
checkRock(no)->lifesucks->affStock
affStock->choix->alea->majFit->clampFit->majStock->clampStock->score->etat
```
## Remarques
- Il faut utiliser start.sh pour avoir une demo du projet

View File

@@ -1,3 +0,0 @@
#!/bin/bash
clang "$1" -o "${1%%.c}".out

325
start.sh Executable file
View File

@@ -0,0 +1,325 @@
#!/usr/bin/env bash
set -u
set -o pipefail
ROOT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
TMP_DIR=$(mktemp -d "${TMPDIR:-/tmp}/cowsay-tour.XXXXXX")
trap 'rm -rf "$TMP_DIR"' EXIT
AUTO_RUN=0
COUNTDOWN=10
STOP_TOUR=0
COMPILER=""
usage() {
cat <<'EOF'
Usage:
./tour_programmes.sh
./tour_programmes.sh --auto
Options:
--auto starts immediately without waiting
-h, --help shows this help
EOF
}
while (($# > 0)); do
case "$1" in
--auto)
AUTO_RUN=1
;;
-h | --help)
usage
exit 0
;;
*)
printf 'Unknown option: %s\n\n' "$1" >&2
usage >&2
exit 1
;;
esac
shift
done
hr() {
printf '\n============================================================\n'
}
show_intro() {
hr
printf 'Quick cowsay program tour\n'
if ((AUTO_RUN == 1)); then
printf 'Auto mode: demos start immediately.\n'
else
printf 'The first demo starts after %d seconds.\n' "$COUNTDOWN"
printf 'After each demo, the tour waits %d seconds before the next one.\n' "$COUNTDOWN"
printf 'Press Enter to continue faster, or type n then Enter to stop.\n'
fi
}
need_commands() {
local missing=0
local cmd
for cmd in "$@"; do
if ! command -v "$cmd" >/dev/null 2>&1; then
printf 'Missing dependency: %s\n' "$cmd" >&2
missing=1
fi
done
return "$missing"
}
detect_compiler() {
if [[ -n "$COMPILER" ]]; then
return 0
fi
local candidate
for candidate in cc clang gcc; do
if command -v "$candidate" >/dev/null 2>&1; then
COMPILER="$candidate"
return 0
fi
done
printf 'No C compiler found.\n' >&2
return 1
}
compile_c() {
local source="$1"
local output="$2"
detect_compiler || return 1
"$COMPILER" -std=c99 -Wall -Wextra -O2 -D_DEFAULT_SOURCE "$source" -o "$output"
}
run_command() {
"$@"
}
run_command_with_input() {
local input="$1"
shift
printf '%s' "$input" | "$@"
}
announce_demo() {
local name="$1"
local description="$2"
hr
printf '%s: %s\n' "$name" "$description"
}
drain_stdin() {
if [[ ! -t 0 ]]; then
return 0
fi
while IFS= read -r -t 0; do
:
done
}
timed_continue() {
local prompt="$1"
if ((AUTO_RUN == 1)) || [[ ! -t 0 ]]; then
printf 'Starting...\n'
return 0
fi
drain_stdin
printf '%s' "$prompt"
local answer=""
if IFS= read -r -t "$COUNTDOWN" answer; then
printf '\n'
case "${answer,,}" in
n)
STOP_TOUR=1
return 1
;;
*)
return 0
;;
esac
fi
printf '\n'
return 0
}
run_demo() {
local name="$1"
local function_name="$2"
"$function_name"
local status=$?
if ((status != 0)); then
printf '%s: failed (%d)\n' "$name" "$status" >&2
fi
}
demo_cow_kindergarten() {
need_commands cowsay || return 1
run_command bash "$ROOT_DIR/src/bash_scripts/cow_kindergarten.sh"
}
demo_cow_primaryschool() {
need_commands cowsay || return 1
run_command bash "$ROOT_DIR/src/bash_scripts/cow_primaryschool.sh" 3
}
demo_cow_highschool() {
need_commands cowsay || return 1
run_command bash "$ROOT_DIR/src/bash_scripts/cow_highschool.sh" 3
}
demo_cow_college() {
need_commands cowsay || return 1
run_command bash "$ROOT_DIR/src/bash_scripts/cow_college.sh" 5
}
demo_cow_university() {
need_commands cowsay || return 1
run_command bash "$ROOT_DIR/src/bash_scripts/cow_university.sh" 12
}
demo_smart_cow() {
need_commands cowsay bc || return 1
run_command bash "$ROOT_DIR/src/bash_scripts/smart_cow.sh" '4+13'
}
demo_crazy_cow() {
need_commands cowsay || return 1
run_command_with_input $'5\n' bash "$ROOT_DIR/src/bash_scripts/crazy_cow.sh"
}
demo_newcow() {
local bin="$TMP_DIR/newcow"
compile_c "$ROOT_DIR/src/C/newcow.c" "$bin" || return 1
run_command "$bin" -e "^^"
}
demo_newcowt() {
local bin="$TMP_DIR/newcowT"
compile_c "$ROOT_DIR/src/C/newcows/newcowT.c" "$bin" || return 1
run_command "$bin" -T "U"
}
demo_newcowp() {
local bin="$TMP_DIR/newcowp"
compile_c "$ROOT_DIR/src/C/newcows/newcowp.c" "$bin" || return 1
run_command "$bin" -p "Hello"
}
demo_newcow2() {
local bin="$TMP_DIR/newcow2"
compile_c "$ROOT_DIR/src/C/newcow2.c" "$bin" || return 1
run_command "$bin" blink
}
demo_reading_cow() {
local bin="$TMP_DIR/reading_cow"
local sample="$TMP_DIR/reading_demo.txt"
compile_c "$ROOT_DIR/src/C/reading_cow.c" "$bin" || return 1
printf 'Hello.\nI read.\n' >"$sample"
run_command "$bin" --i 0.10 "$sample"
}
demo_tamagoshi_cow() {
local bin="$TMP_DIR/tamagoshi_cow"
if ((AUTO_RUN == 1)) || [[ ! -t 0 ]]; then
printf 'Tamagoshi skipped in auto mode.\n'
return 0
fi
compile_c "$ROOT_DIR/src/C/tamagoshi_cow.c" "$bin" || return 1
run_command "$bin"
}
visit_programs() {
local -a names=(
'cow_kindergarten.sh'
'cow_primaryschool.sh'
'cow_highschool.sh'
'cow_college.sh'
'cow_university.sh'
'smart_cow.sh'
'crazy_cow.sh'
'newcow.c'
'newcowT.c'
'newcowp.c'
'newcow2.c'
'reading_cow.c'
'tamagoshi_cow.c'
)
local -a descriptions=(
'Counts from 1 to 10.'
'Counts up to n.'
'Shows square numbers.'
'Shows Fibonacci.'
'Shows prime numbers.'
'Calculates an expression.'
'Generates a weird sequence.'
'Basic cow.'
'Cow with a tongue option.'
'Cow with a speech bubble.'
'Compiles a .c file into .out.'
'Animates the cow.'
'The cow reads a file.'
'Small cow game.'
)
local -a functions=(
'demo_cow_kindergarten'
'demo_cow_primaryschool'
'demo_cow_highschool'
'demo_cow_college'
'demo_cow_university'
'demo_smart_cow'
'demo_crazy_cow'
'demo_newcow'
'demo_newcowt'
'demo_newcowp'
'demo_newcow2'
'demo_reading_cow'
'demo_tamagoshi_cow'
)
local total=${#names[@]}
local i
for ((i = 0; i < total; i++)); do
announce_demo "${names[i]}" "${descriptions[i]}"
if ((i == 0)); then
timed_continue "Press Enter to start, type n then Enter to stop, auto-start in ${COUNTDOWN} seconds... " || return
else
timed_continue "Press Enter to start the next program, type n then Enter to stop, or wait ${COUNTDOWN} seconds... " || return
fi
run_demo "${names[i]}" "${functions[i]}"
((STOP_TOUR == 1)) && return
done
}
show_outro() {
hr
if ((STOP_TOUR == 1)); then
printf 'Tour stopped.\n'
else
printf 'End of tour.\n'
fi
}
show_intro
visit_programs
show_outro