Commit 024b4b31 authored by William Babonnaud's avatar William Babonnaud

Merge branch 'master' of gitlab.crans.org:arrighi/prog2

parents c4b4e844 0f5dee38
import scala.util.Random
import Array._
import javax.swing.ImageIcon
import scala.math._
class Demineur extends Jeu[MonBouton] {
// Taille du champ de mine. Par défaut, réglé en "Facile".
tailleX = 9
tailleY = 9
// Propage le clic pour le premier coup après non
private var premierCoup = true
// Nombre de mines dans le champ. Réglé en "Facile"
private var nb_mines = 10
// Compteur du nombre de mines trouvées.
private var m_trouvees = 0
// Compteur du nombre de cases restantes.
private var c_restantes = {tailleX*tailleY - nb_mines}
// Détermine si on a gagné.
def victoire() = {(nb_mines == m_trouvees) || c_restantes == 0}
// Matrice représentant le champ de mines. Ses valeurs sont comprises entre 0 et 9.
// 0-8 : Nombre de mines autour de la case vide.
// 9 : Signale l'emplacement d'une mine sur la case.
// Par défaut, on est réglé sur facile.
// private var champ = ofDim[Int](tailleX,tailleY)
// Matrice des boutons associés aux cases (il me semble plus pertinent de l'inclure dans le jeu).
protected var boutons = ofDim[MonBouton](tailleX,tailleY)
// Réinitialise les paramètres ci-dessus en cas de changement de difficulté.
def reparametrage (x: Int, y: Int, n: Int) = {
tailleX = x
tailleY = y
nb_mines = n
c_restantes = tailleX*tailleY - nb_mines
// champ = ofDim[Int](tailleX, tailleY)
boutons = ofDim[MonBouton](tailleX, tailleY)
}
// Pour récupérer les valeurs tailleX et tailleY
def getTailleX = tailleX
def getTailleY = tailleY
// Pour récupérer la matrice de boutons.
def getBoutons(x : Int, y : Int) = boutons(x)(y)
// Réactive la variable de premier coup
def resetPremierCoup = premierCoup = true
// (Re)crée un champ de boutons sans toucher aux valeurs
def creation_boutons = {
map_init((i,j) => new MonBouton(i,j), boutons)
}
// Initialisation basique d'un champ de mine.
// On crée les boutons ; puis on génère nb_mines positions aléatoires, et on
// incrémente les cases alentour pour chaque mine placée.
def initialise = {
creation_boutons
var x = Random.nextInt(tailleX)
var y = Random.nextInt(tailleY)
for (i <- 0 to min(nb_mines-1,tailleX*tailleY-1)) {
while(boutons(x)(y).getContenu == 9) {
x = Random.nextInt(tailleX)
y = Random.nextInt(tailleY)
}
boutons(x)(y).setContenu(9)
if (x != 0) {
if (!boutons(x-1)(y).mines) { boutons(x-1)(y).incrContenu}
}
if (x != (tailleX-1)) {
if (!boutons(x+1)(y).mines) { boutons(x+1)(y).incrContenu}
}
if (y != 0) {
if (!boutons(x)(y-1).mines) { boutons(x)(y-1).incrContenu}
}
if (y != (tailleY-1)) {
if (!boutons(x)(y+1).mines) { boutons(x)(y+1).incrContenu}
}
if (x != 0 && y != 0) {
if (!boutons(x-1)(y-1).mines) { boutons(x-1)(y-1).incrContenu}
}
if (x != 0 && y != (tailleY-1)) {
if (!boutons(x-1)(y+1).mines) { boutons(x-1)(y+1).incrContenu}
}
if (x != (tailleX-1) && y != 0) {
if (!boutons(x+1)(y-1).mines) { boutons(x+1)(y-1).incrContenu}
}
if (x != (tailleX-1) && y != (tailleY-1)) {
if (!boutons(x+1)(y+1).mines) { boutons(x+1)(y+1).incrContenu}
}
}
}
// Même fonction, mais avec la composante "random seed" en paramètre.
def initialise (n: Int) = {
creation_boutons
var ran = new Random(n)
var x = ran.nextInt(tailleX)
var y = ran.nextInt(tailleY)
for (i <- 0 to min(nb_mines-1,tailleX*tailleY-1)) {
while(boutons(x)(y).getContenu == 9) {
x = ran.nextInt(tailleX)
y = ran.nextInt(tailleY)
}
boutons(x)(y).setContenu(9)
if (x != 0) {
if (!boutons(x-1)(y).mines) { boutons(x-1)(y).incrContenu}
}
if (x != (tailleX-1)) {
if (!boutons(x+1)(y).mines) { boutons(x+1)(y).incrContenu}
}
if (y != 0) {
if (!boutons(x)(y-1).mines) { boutons(x)(y-1).incrContenu}
}
if (y != (tailleY-1)) {
if (!boutons(x)(y+1).mines) { boutons(x)(y+1).incrContenu}
}
if (x != 0 && y != 0) {
if (!boutons(x-1)(y-1).mines) { boutons(x-1)(y-1).incrContenu}
}
if (x != 0 && y != (tailleY-1)) {
if (!boutons(x-1)(y+1).mines) { boutons(x-1)(y+1).incrContenu}
}
if (x != (tailleX-1) && y != 0) {
if (!boutons(x+1)(y-1).mines) { boutons(x+1)(y-1).incrContenu}
}
if (x != (tailleX-1) && y != (tailleY-1)) {
if (!boutons(x+1)(y+1).mines) { boutons(x+1)(y+1).incrContenu}
}
}
}
// Propagation du dévoilement des cases vides
private def propage(c: Int, x: Int, y: Int){
if(c == 0 || premierCoup){
if(premierCoup){premierCoup = false}
if (x > 0) {
if(boutons(x-1)(y).estLibre && !boutons(x-1)(y).mines){clique_action(x-1,y)}
if(y > 0){
if(boutons(x-1)(y-1).estLibre && !boutons(x-1)(y-1).mines){clique_action(x-1,y-1)}
}
if(y < tailleY-1){
if(boutons(x-1)(y+1).estLibre && !boutons(x-1)(y+1).mines){clique_action(x-1,y+1)}
}
}
if (x < tailleX-1) {
if(boutons(x+1)(y).estLibre && !boutons(x+1)(y).mines){clique_action(x+1,y)}
if(y > 0){
if(boutons(x+1)(y-1).estLibre && !boutons(x+1)(y-1).mines){clique_action(x+1,y-1)}
}
if(y < tailleY-1){
if(boutons(x+1)(y+1).estLibre && !boutons(x+1)(y+1).mines){clique_action(x+1,y+1)}
}
}
if(y>0){
if(boutons(x)(y-1).estLibre && !boutons(x)(y-1).mines){clique_action(x,y-1)}
}
if(y<tailleY-1){
if(boutons(x)(y+1).estLibre && !boutons(x)(y+1).mines){clique_action(x,y+1)}
}
}
}
def devoile (x: Int, y: Int) = {
var perdu = false
if (x > 0) {
if(boutons(x-1)(y).estLibre){perdu = perdu || clique_action(x-1,y)}
if(y > 0){
if(boutons(x-1)(y-1).estLibre){perdu = perdu || clique_action(x-1,y-1)}
}
if(y < tailleY-1){
if(boutons(x-1)(y+1).estLibre){perdu = perdu || clique_action(x-1,y+1)}
}
}
if (x < tailleX-1) {
if(boutons(x+1)(y).estLibre){perdu = perdu || clique_action(x+1,y)}
if(y > 0){
if(boutons(x+1)(y-1).estLibre){perdu = perdu || clique_action(x+1,y-1)}
}
if(y < tailleY-1){
if(boutons(x+1)(y+1).estLibre){perdu = perdu || clique_action(x+1,y+1)}
}
}
if(y>0){
if(boutons(x)(y-1).estLibre){perdu = perdu || clique_action(x,y-1)}
}
if(y<tailleY-1){
if(boutons(x)(y+1).estLibre){perdu = perdu || clique_action(x,y+1)}
}
perdu
}
// Définit les conséquences d'un clic sur un bouton.
def clique_action (x: Int, y: Int) : Boolean = {
if(boutons(x)(y).estLibre){ //Cases non dévoilée, on la dévoile
boutons(x)(y).getContenu match {
case 0 => boutons(x)(y).icon = new ImageIcon(getClass.getResource("case_zero.png"))
boutons(x)(y).enabled = false
boutons(x)(y).chgLibre
boutons(x)(y).disabledIcon = new ImageIcon(getClass.getResource("case_zero.png"))
c_restantes -= 1
propage(0,x,y)
false
case 1 => boutons(x)(y).icon = new ImageIcon(getClass.getResource("case_un.png"))
boutons(x)(y).disabledIcon = new ImageIcon(getClass.getResource("case_un.png"))
boutons(x)(y).chgLibre
c_restantes -= 1
propage(1,x,y)
false
case 2 => boutons(x)(y).icon = new ImageIcon(getClass.getResource("case_deux.png"))
boutons(x)(y).disabledIcon = new ImageIcon(getClass.getResource("case_deux.png"))
boutons(x)(y).chgLibre
c_restantes -= 1
propage(2,x,y)
false
case 3 => boutons(x)(y).icon = new ImageIcon(getClass.getResource("case_trois.png"))
boutons(x)(y).disabledIcon = new ImageIcon(getClass.getResource("case_trois.png"))
boutons(x)(y).chgLibre
c_restantes -= 1
propage(3,x,y)
false
case 4 => boutons(x)(y).icon = new ImageIcon(getClass.getResource("case_quatre.png"))
boutons(x)(y).disabledIcon = new ImageIcon(getClass.getResource("case_quatre.png"))
boutons(x)(y).chgLibre
c_restantes -= 1
propage(4,x,y)
false
case 5 => boutons(x)(y).icon = new ImageIcon(getClass.getResource("case_cinq.png"))
boutons(x)(y).disabledIcon = new ImageIcon(getClass.getResource("case_cinq.png"))
boutons(x)(y).chgLibre
c_restantes -= 1
propage(5,x,y)
false
case 6 => boutons(x)(y).icon = new ImageIcon(getClass.getResource("case_six.png"))
boutons(x)(y).disabledIcon = new ImageIcon(getClass.getResource("case_six.png"))
boutons(x)(y).chgLibre
c_restantes -= 1
propage(6,x,y)
false
case 7 => boutons(x)(y).icon = new ImageIcon(getClass.getResource("case_sept.png"))
boutons(x)(y).disabledIcon = new ImageIcon(getClass.getResource("case_sept.png"))
boutons(x)(y).chgLibre
c_restantes -= 1
propage(7,x,y)
false
case 8 => boutons(x)(y).icon = new ImageIcon(getClass.getResource("case_huit.png"))
boutons(x)(y).disabledIcon = new ImageIcon(getClass.getResource("case_huit.png"))
boutons(x)(y).chgLibre
c_restantes -= 1
propage(8,x,y)
false
case 9 => for (i <- 0 to (tailleX-1)) {
for (j <- 0 to (tailleY-1)) {
if (boutons(i)(j).mines) {
boutons(x)(y).chgLibre
boutons(i)(j).icon = new ImageIcon(getClass.getResource("case_mine.png"))
boutons(i)(j).enabled = false
boutons(i)(j).disabledIcon = new ImageIcon(getClass.getResource("case_mine.png"))
}
}
}
true
}
} else {// Cases déjà dévoilée, on dévoile le tour
devoile(x,y)
}
}
// Affichage des drapeaux
def drapeau(x: Int, y: Int) = {
if (boutons(x)(y).enabled == true) {
boutons(x)(y).icon = new ImageIcon(getClass.getResource("case_drapeau.png"))
boutons(x)(y).enabled = false
boutons(x)(y).chgLibre
boutons(x)(y).chgDrapeau
boutons(x)(y).disabledIcon = new ImageIcon(getClass.getResource("case_drapeau.png"))
if (boutons(x)(y).mines) { m_trouvees += 1 } else { m_trouvees -= 1 }
}
else {
if (boutons(x)(y).possedeDrapeau) {
boutons(x)(y).icon = scala.swing.Swing.EmptyIcon
boutons(x)(y).enabled = true
boutons(x)(y).chgLibre
boutons(x)(y).chgDrapeau
if (boutons(x)(y).mines) { m_trouvees -= 1 } else { m_trouvees += 1 }
}
}
}
}
import swing._
import java.awt.Color
import javax.swing.ImageIcon
class MonBouton(protected var x : Int, protected var y : Int) extends Button {
preferredSize = new Dimension(50, 50)
borderPainted = true
private var contenu = 0 // 0-8 nbre mines, 9 mine
private var libre = true //case sans rien
private var drapeau = false
def getTheX = x
def getTheY = y
def estLibre = libre
def chgLibre = libre = !libre
def possedeDrapeau = drapeau
def chgDrapeau = drapeau = !drapeau
def setContenu(n:Int) = contenu = n
def getContenu = contenu
def incrContenu = contenu += 1
def mines = contenu == 9
def reset =
libre = true
drapeau = false
}
import scala.util.Random
import swing._
import Array._
import javax.swing.ImageIcon
import scala.math._
abstract class Jeu[T<:Button] {
protected var tailleX : Int = 9
protected var tailleY : Int = 9
protected var boutons : Array[Array[T]]
protected def map_init(f : (Int,Int) => T, a : Array[Array[T]]) = {
for (i <- 0 to (tailleX-1))
for (j <- 0 to (tailleY-1))
a(i)(j) = f(i,j)
}
protected def map_apply(f : T => Unit, a : Array[Array[T]]) = {
a.map(x => x.map(f))
}
def victoire() : Boolean
}
import swing._
import event._
import Array._
import java.awt.{Color, Graphics2D}
import javax.swing.ImageIcon
object CercleInvocation extends SimpleSwingApplication {
def top = new MainFrame {
// Valeurs et variables.
private var jeu = new Demineur
// Convertisseur sécurisé
private def string_to_int (s: String) = {
try {
s.toInt
} catch {
case e:Exception => 0
}
}
private val but_fac = new RadioButton("Facile")
private val but_moy = new RadioButton("Moyen")
private val but_dur = new RadioButton("Difficile")
private val but_per = new RadioButton("Personnalisé")
private val mutex = new ButtonGroup(but_fac, but_moy, but_dur, but_per)
mutex.select(but_fac)
// Création d'un nouveau jeu
private def new_game = {
jeu = new Demineur
mutex.selected.get match {
case `but_fac` =>
case `but_moy` => jeu.reparametrage(16,16,40)
case `but_dur` => jeu.reparametrage(16,16,99)
case `but_per` => val r_lig = Dialog.showInput(contents.head, "Entrez le nombre de lignes :",
title="Génération personnalisée", initial = "9",
icon = new ImageIcon(getClass.getResource("case_un.png")))
val r_col = Dialog.showInput(contents.head, "Entrez le nombre de colonnes :",
title="Génération personnalisée", initial = "9",
icon = new ImageIcon(getClass.getResource("case_deux.png")))
val r_mine = Dialog.showInput(contents.head, "Entrez le nombre de mines :",
title="Génération personnalisée", initial = "10",
icon = new ImageIcon(getClass.getResource("case_trois.png")))
var li = 9
var co = 9
var nm = 10
r_lig match {
case Some(s) => if (string_to_int(s) != 0) { li = string_to_int(s) }
case None =>
}
r_col match {
case Some(s) => if (string_to_int(s) != 0) { co = string_to_int(s) }
case None =>
}
r_mine match {
case Some(s) => if (string_to_int(s) != 0) { nm = string_to_int(s) }
case None =>
}
jeu.reparametrage(li,co,nm)
}
jeu.initialise
contents = genContents
listen
}
// Activation des surveillances de boutons.
private def listen =
for (i <- 0 to (jeu.getTailleX-1)) {
for (j <- 0 to (jeu.getTailleY-1)) {
listenTo(jeu.getBoutons(i,j))
listenTo(jeu.getBoutons(i,j).mouse.clicks)
}
}
// Genesation de la grille
private def genContents =
new GridPanel(jeu.getTailleX,jeu.getTailleY) {
for (i <- 0 to (jeu.getTailleX-1)) {
for (j <- 0 to (jeu.getTailleY-1)) {
contents += jeu.getBoutons(i,j)
}
}
}
// Redémarrage du jeu
private def redemarrage = {
for (i <- 0 to (jeu.getTailleX-1)) {
for (j <- 0 to (jeu.getTailleY-1)) {
jeu.getBoutons(i,j).reset
jeu.getBoutons(i,j).icon = scala.swing.Swing.EmptyIcon
jeu.getBoutons(i,j).enabled = true
}
}
jeu.resetPremierCoup
contents = genContents
listen
}
// Génération à partir d'une graine aléatoire
private def genere_a_parametre = {
val r = Dialog.showInput(contents.head, "Entrez une graine de génération :",
title="Génération paramétrée", initial = "12",
icon = new ImageIcon(getClass.getResource("case_mine.png")))
r match {
case Some(s) => jeu = new Demineur
mutex.selected.get match {
case `but_fac` =>
case `but_moy` => jeu.reparametrage(16,16,40)
case `but_dur` => jeu.reparametrage(16,16,99)
case `but_per` => val r_lig = Dialog.showInput(contents.head, "Entrez le nombre de lignes :",
title="Génération personnalisée", initial = "9",
icon = new ImageIcon(getClass.getResource("case_un.png")))
val r_col = Dialog.showInput(contents.head, "Entrez le nombre de colonnes :",
title="Génération personnalisée", initial = "9",
icon = new ImageIcon(getClass.getResource("case_deux.png")))
val r_mine = Dialog.showInput(contents.head, "Entrez le nombre de mines :",
title="Génération personnalisée", initial = "10",
icon = new ImageIcon(getClass.getResource("case_trois.png")))
var li = 9
var co = 9
var nm = 10
r_lig match {
case Some(s) => if (string_to_int(s) > 0) { li = string_to_int(s) }
case None =>
}
r_col match {
case Some(s) => if (string_to_int(s) > 0) { co = string_to_int(s) }
case None =>
}
r_mine match {
case Some(s) => if (string_to_int(s) > 0) { nm = string_to_int(s) }
case None =>
}
jeu.reparametrage(li,co,nm)
}
jeu.initialise(string_to_int(s))
contents = genContents
listen
case None =>
}
}
// Création d'un jeu initial.
jeu.initialise
// Elément de décor.
title = "The Great Satanist Programming Project"
// Barre de menu.
menuBar = new MenuBar {
contents += new Menu("Jeu") {
contents += new MenuItem(Action("Nouveau jeu") {
new_game
})
contents += new MenuItem(Action("Redémarrer") {
redemarrage
})
contents += new MenuItem(Action("Génération paramétrée...") {
genere_a_parametre
})
contents += new Menu("Difficulté") {
contents ++= mutex.buttons
}
contents += new MenuItem(Action("Sortir"){
sys.exit(0)
})
}
}
//contents += new Label("Il te reste 10 mines !")
// Elements de la fenêtre.
contents = genContents
// Activation des surveillances de boutons.
listen
// Réaction aux évènements.
reactions += {
case ButtonClicked(component : MonBouton) => var bo = jeu.clique_action(component.getTheX, component.getTheY)
if (bo) {
Dialog.showMessage(contents.head, "Désolé, vous avez perdu !", "Boum !!!",
Dialog.Message.Info, new ImageIcon(getClass.getResource("case_mine.png")))
redemarrage
} else {
if (jeu.victoire) {
Dialog.showMessage(contents.head, "Félicitations, vous avez gagné !", "Victoire !!!",
Dialog.Message.Info, new ImageIcon(getClass.getResource("case_drapeau.png")))
new_game
} }
case (e: MouseEvent) => if (e.peer.getButton() == java.awt.event.MouseEvent.BUTTON3) {
jeu.drapeau(e.peer.getComponent.getY/50, e.peer.getComponent.getX/50)
if (jeu.victoire) {
Dialog.showMessage(contents.head, "Félicitations, vous avez gagné !", "Victoire !!!",
Dialog.Message.Info, new ImageIcon(getClass.getResource("case_drapeau.png")))
new_game
}
}
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment