dimanche 30 mars 2008

Jeu de Nim en Fortran

Vous connaissez peut-être le jeu de Nim sous le nom de "jeu des allumettes"... Version Frotran 90 "sale" ("Goto statement considered harmfull", non respect des normes actuelles...) en mode console. Au passage, je teste l'outil de conversion html de (g)Vim (f*ck it ça passe pas...)... Got a problem homie ? Just tell me (give my money and buy my medecine...). Version collée chez Pastie pour plus de lisibilité (lignes trop longues, etc...) : goto ICI.

Ze code :
(compilé avec GFortran (fortran 90) sous Windows)


Program Jeu_de_Nim
IMPLICIT NONE

integer :: nbre_allum, ordre, choix, scorePC, scoreHumain, nb_parties, i, aleas
logical :: PC_first, tournoi


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! BIENVENUE
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

print*, "!!!!!!!!!!!!!!!"
print*, "JEU DE NIM v2.0"
print*, "!!!!!!!!!!!!!!!"
print*, "Bienvenue dans ce petit jeu de Nim."

print*, "A chaque tour, le joueur ou le PC doivent prendre 1, 2 ou 3 allumettes."
print*, "Celui qui prend la derniere allumette a perdu. Bonne chance."
print*, " "

scorePC = 0
scoreHumain = 0
tournoi = .FALSE.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! MENU

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
111 print*, "Entrez votre choix :"
print*, "[0] : Nouvelle Partie"
print*, "[1] : Nouveau Tournoi"
print*, "[2] : Afficher Scores"

print*, "[3] : Reinitialiser les Scores"
print*, "[4] : Quitter"
read*, choix

SELECT CASE (choix)
CASE (0)
GOTO 222
CASE (1)
tournoi = .TRUE.
scorePC = 0
scoreHumain = 0
11 print*, "Tournoi en combien de parties ?"

read*, nb_parties
if (nb_parties < 1) then
print*, "Tssss... Trop drole..."
GOTO 11
end if

aleas = 2*rand()

PC_first = .TRUE.
IF (aleas == 1) PC_first = .FALSE.
i = 0
10 i = i+1
print*, "PARTIE numero : ", i
call Afficher_scores(scorePC, scoreHumain)
IF (i > nb_parties) then
call Afficher_scores(scorePC, scoreHumain)
if (scorePC > scoreHumain) print*, "LE PC GAGNE LE TOURNOI !!!"

if (scorePC == scoreHumain) print*, "EGALITE !!! INCROYABLE !!!"
if (scorePC < scoreHumain) print*, "VOUS GAGNEZ LE TOURNOI !!! BRAVO !!!"
GOTO 111
END IF


nbre_allum = 50*rand() + 1
PC_first = .NOT.PC_first
GOTO 223

CASE (2)
call Afficher_scores(scorePC, scoreHumain)
GOTO 111

CASE (3)
scorePC = 0
scoreHumain = 0
GOTO 111

CASE (4)
GOTO 666

CASE DEFAULT

print*, "Mauvais choooooooooooix......"
GOTO 111

END SELECT

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! PARTIE
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

222 print*, "Combien d'allumettes pour la partie ? (0 pour un nombre au hasard)"
read*, nbre_allum
if (nbre_allum == 0) nbre_allum = 50*rand()+1
if (nbre_allum < 0) then
print*, "Hummmmmm... Pas beaucoup ca..."
GOTO 222
end if
print*, "Qui joue en premier ?"

print*, "[1] : PC"
print*, "[2] : Humain"
print*, "[3] : Au hasard"
read*, ordre

SELECT CASE (ordre)
CASE (1)
PC_first = .TRUE.
print*, "Le PC commence."

CASE (2)
PC_first = .FALSE.
print*, "L'humain commence."
CASE (3)
aleas = 2*rand()
PC_first = .TRUE.
IF (aleas > 1) PC_first = .FALSE.
CASE DEFAULT

PC_first = .TRUE.
print*, "Apprends a taper cono !"
print*, "Du coup le PC commence..."
END SELECT

223 IF (PC_first) THEN

do while (nbre_allum > 0)
call Tour_de_jeu_PC(nbre_allum,scoreHumain)
IF (nbre_allum > 0) call Tour_de_jeu_Humain(nbre_allum,scorePC)
end do
ELSE
do while (nbre_allum > 0)
call Tour_de_jeu_Humain(nbre_allum,scorePC)
IF (nbre_allum > 0) call Tour_de_jeu_PC(nbre_allum,scoreHumain)
end do
END IF

IF (tournoi) GOTO 10

GOTO 111

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

! EXIT
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
666 print*, "MERCI, A BIENTOT !"

End Program Jeu_de_Nim

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! AFFICHAGE DES SCORES
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Subroutine Afficher_scores(scPC, scHuman)
integer, intent(in) :: scPC, scHuman

print*, "!!!!! SCORE !!!!!"

print*, "PC : ", scPC
print*, "Humain : ", scHuman

End Subroutine Afficher_scores

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! TOUR PC
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Subroutine Tour_de_jeu_PC(nb_al, scHuman)
integer, intent(inout) :: nb_al, scHuman
integer :: reste, prise

print*, "Il y a ", nb_al, "allumettes."

reste = MOD(nb_al,4)

if (nb_al == 1) then
prise = 1
else
SELECT CASE (reste)
CASE (1)
prise = 3*rand()+1
CASE (2)
prise = 1
CASE (3)
prise = 2
CASE (0)
prise = 3
CASE DEFAULT

print*, "Erreur : module inconsistant"
print*, "Module = ", reste
STOP
END SELECT
end if

nb_al = nb_al - prise
print*, "Le PC prend ", prise, " allumettes."

print*, "Il reste : ", nb_al, "allumettes."

if (nb_al == 0) then
print*, "VOUS AVEZ GAGNE !!!!! FELICITATIONS !!!!"
scHuman = scHuman + 1
end if

End Subroutine Tour_de_jeu_PC


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
! TOUR HUMAIN
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
Subroutine Tour_de_jeu_Humain(nb_al, scPC)
integer, intent(inout) :: nb_al, scPC
integer :: prise

print*, "Il y a ", nb_al, "allumettes."

print*, "Combien souhaitez vous en prendre ? (1, 2 ou 3)"
999 read*, prise

if ((prise > 3).OR.(prise < 1).OR.(prise > nb_al)) then
print*, "Nombre saisi incorrect : veuillez recommencer."
GOTO 999
end if

nb_al = nb_al - prise
print*, "Vous avez pris ", prise, " allumettes."

print*, "Il reste : ", nb_al, "allumettes."

if (nb_al == 0) then
print*, "VOUS AVEZ PERDU !!!!!"
scPC = scPC + 1
end if

End Subroutine Tour_de_jeu_Humain

0 commentaires: