J'ai créé une sorte de jeu de puzzle dans lequel l'objectif est de se débarrasser de toutes les tuiles blanches. Vous pouvez l'essayer à la fin de la question.
À chaque fois, le tableau est généré de manière aléatoire avec des carreaux blancs à des emplacements aléatoires sur une grille 5 * 5. Vous pouvez cliquer sur n’importe quelle tuile de cette grille et celle-ci changera de couleur et toutes les tuiles le toucheront sur les côtés. Mon dilemme est le fait que je ne sais pas si cela va générer un conseil impossible. Quel est le meilleur moyen de vérifier de telles choses?
function newgame() {
moves = 0;
document.getElementById("moves").innerHTML = "Moves: "+moves;
for (var i = 0; i < 25; i++) {
if (Math.random() >= 0.5) {
$(document.getElementsByClassName('block')[i]).toggleClass("b1 b2")
}
}
}
newgame();
function toggle(a,b) {
moves += 1;
document.getElementById("moves").innerHTML = "Moves: "+moves;
$(document.getElementsByClassName('block')[a+(b*5)]).toggleClass("b1 b2");
if (a<4) {$(document.getElementsByClassName('block')[(a+1)+(b*5)]).toggleClass("b1 b2")}
if (a>0) {$(document.getElementsByClassName('block')[(a-1)+(b*5)]).toggleClass("b1 b2")}
if (b<4) {$(document.getElementsByClassName('block')[a+((b+1)*5)]).toggleClass("b1 b2")}
if (b>0) {$(document.getElementsByClassName('block')[a+((b-1)*5)]).toggleClass("b1 b2")}
}
body {
background-color: #000000;
}
.game {
float: left;
background-color: #000000;
width: 300px;
height: 300px;
overflow: hidden;
overflow-x: hidden;
user-select: none;
display: inline-block;
}
.container {
border-color: #ffffff;
border-width: 5px;
border-style: solid;
border-radius: 5px;
width: 600px;
height: 300px;
text-align: center;
}
.side {
float: left;
background-color: #000000;
width: 300px;
height: 300px;
overflow: hidden;
overflow-x: hidden;
user-select: none;
display: inline-block;
}
.block {
transition: background-color 0.2s;
float: left;
}
.b1:hover {
background-color: #444444;
cursor: pointer;
}
.b2:hover {
background-color: #bbbbbb;
cursor: pointer;
}
.row {
width: 300px;
overflow: auto;
overflow-x: hidden;
}
.b1 {
display: inline-block;
height: 50px;
width: 50px;
background-color: #000000;
border-color: #000000;
border-width: 5px;
border-style: solid;
}
.b2 {
display: inline-block;
height: 50px;
width: 50px;
background-color: #ffffff;
border-color: #000000;
border-width: 5px;
border-style: solid;
}
.title {
width: 200px;
height: 50px;
color: #ffffff;
font-size: 55px;
font-weight: bold;
font-family: Arial;
display: table-cell;
vertical-align: middle;
}
.button {
cursor: pointer;
width: 200px;
height: 50px;
background-color: #000000;
border-color: #ffffff;
border-style: solid;
border-width: 5px;
color: #ffffff;
font-size: 25px;
font-weight: bold;
font-family: Arial;
display: table-cell;
vertical-align: middle;
border-radius: 5px;
transition: background-color 0.3s, color 0.3s;
}
.button:hover {
background-color: #ffffff;
color: #000000;
}
.sidetable {
padding: 30px 0px;
height: 200px;
}
#moves {
width: 200px;
height: 50px;
color: #aaaaaa;
font-size: 30px;
font-weight: bold;
font-family: Arial;
display: table-cell;
vertical-align: middle;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<center>
<div class="container">
<div class="game"><div class="row"><div onclick="toggle(0,0);" class="block b1"></div><div onclick="toggle(1,0);" class="block b1"></div><div onclick="toggle(2,0);" class="block b1"></div><div onclick="toggle(3,0);" class="block b1"></div><div onclick="toggle(4,0);" class="block b1"></div></div><div class="row"><div onclick="toggle(0,1);" class="block b1"></div><div onclick="toggle(1,1);" class="block b1"></div><div onclick="toggle(2,1);" class="block b1"></div><div onclick="toggle(3,1);" class="block b1"></div><div onclick="toggle(4,1);" class="block b1"></div></div><div class="row"><div onclick="toggle(0,2);" class="block b1"></div><div onclick="toggle(1,2);" class="block b1"></div><div onclick="toggle(2,2);" class="block b1"></div><div onclick="toggle(3,2);" class="block b1"></div><div onclick="toggle(4,2);" class="block b1"></div></div><div class="row"><div onclick="toggle(0,3);" class="block b1"></div><div onclick="toggle(1,3);" class="block b1"></div><div onclick="toggle(2,3);" class="block b1"></div><div onclick="toggle(3,3);" class="block b1"></div><div onclick="toggle(4,3);" class="block b1"></div></div><div class="row"><div onclick="toggle(0,4);" class="block b1"></div><div onclick="toggle(1,4);" class="block b1"></div><div onclick="toggle(2,4);" class="block b1"></div><div onclick="toggle(3,4);" class="block b1"></div><div onclick="toggle(4,4);" class="block b1"></div></div></div>
<div class="side">
<center class="sidetable">
<div class="title">Tiles</div>
<br>
<div class="button" onclick="newgame()">New Game</div>
<br><br>
<div id="moves">Moves: 0</div>
</center>
</div>
</div>
</center>
game-design
logic
puzzle
playtesting
Qwerty
la source
la source
Réponses:
C'est le type de jeu où le même coup effectué deux fois fait revenir le tableau à son état précédent. Donc, pour que le tableau soit résoluble, générez-le en jouant à l'envers. Commencez par un tableau résolu (vierge), puis démarrez par programme en "cliquant" de manière aléatoire, soit un certain nombre de fois, soit jusqu'à ce que le tableau dispose du nombre souhaité de carrés blancs. Une solution consiste alors simplement à effectuer les mêmes mouvements dans l’ordre inverse. D'autres solutions plus courtes peuvent exister, mais vous êtes assuré d'en avoir au moins une.
Une autre solution, beaucoup plus complexe, consiste à définir un algorithme de résolution qui passe par tous les états de jeu possibles à partir de votre position de départ pour essayer de trouver la solution. Cela prendrait beaucoup plus de temps à mettre en œuvre et à exécuter, mais permettrait aux cartes d'être réellement générées de manière aléatoire. Je n'entrerai pas dans les détails de cette solution, car ce n'est tout simplement pas une bonne idée.
la source
Bien que les réponses ci-dessus soient intelligentes (et probablement comment je le ferais de toute façon), ce jeu est très connu. Cela s'appelle Lights Out et a été résolu mathématiquement. Il existe une solution si et seulement si deux sommes d'éléments différents (indiquées sur la page wikipedia) s'ajoutent à zéro mod 2 (c'est-à-dire un nombre pair). En général, un peu d'algèbre linéaire devrait donner des conditions de solution similaires pour les jeux sur n'importe quel tableau.
la source
Faites l'inverse pour générer votre puzzle.
Au lieu de sélectionner au hasard les carreaux et de les passer du blanc au noir, commencez par une ardoise vierge, puis sélectionnez les carreaux, mais au lieu de noircir ce carreau, faites-le comme si l'utilisateur l'avait sélectionné, ce qui ferait basculer tous les autres carreaux. autour de.
De cette façon, vous aurez la garantie d’avoir au moins une solution: l’utilisateur devra annuler ce que votre joueur "IA" a fait pour créer le niveau.
la source
Ed et Alexandre en ont le droit.
Mais si vous ne voulez savoir si chaque solution est possible, il existe des moyens.
Il y a un nombre fini de puzzles possibles
En cliquant deux fois sur le même carré, on obtient le même résultat que de ne pas cliquer dessus, quel que soit le nombre de clics enregistrés. Cela signifie que chaque solution peut être décrite en attribuant à chaque carré une valeur binaire «cliqué» ou «non cliqué». De même, chaque casse-tête peut être décrit en attribuant à chaque carré une valeur binaire «basculée» ou «non basculée». Cela signifie qu'il y a 2 ^ 25 énigmes possibles et 2 ^ 25 solutions possibles. Si vous pouvez prouver que chaque solution résout un casse-tête unique, il doit exister une solution à chaque casse-tête. De même, si vous trouvez deux solutions qui résolvent le même casse-tête, il ne peut y avoir de solution à chaque casse-tête.
En outre, 2 ^ 25 est 33,554,432. C'est beaucoup, mais ce n'est pas un nombre ingérable. Un bon algorithme et un ordinateur correct pourraient probablement avoir une force brute d’ici quelques heures, en particulier si l’on considère que la moitié des énigmes sont des inverses de l’autre.
la source
Réponse généralisée:
la source
D'autres ont déjà mentionné des moyens de déterminer si votre puzzle généré de manière aléatoire peut être résolu. La question que vous devriez également vous poser cependant est de savoir si vous voulez réellement des énigmes générés aléatoirement.
Les puzzles générés aléatoirement ont tous le même défaut fondamental: leur difficulté est quasiment imprévisible. Les énigmes possibles peuvent aller de déjà résolues à triviales (la solution est évidente) à difficiles (la solution n'est pas évidente) à impossibles (le casse-tête ne peut pas être résolu du tout). Parce que la difficulté est imprévisible, cela rend le joueur peu satisfaisant, surtout s'il fait plusieurs énigmes à la suite. Il est très peu probable qu'ils obtiennent une courbe de difficulté fluide, ce qui peut les ennuyer ou les frustrer selon les énigmes qu'ils rencontrent.
Un autre problème de la génération aléatoire est que le temps nécessaire à l'initialisation du puzzle est imprévisible. En règle générale, vous obtiendrez (presque) immédiatement une énigme que vous pourrez résoudre, mais avec un peu de malchance, vos énigmes générées aléatoirement risquent de se retrouver sur une série de énigmes insolubles.
Une façon de résoudre ces deux problèmes consiste à disposer de vecteurs prédéfinis de chaque puzzle résoluble disponibles, classés en groupes de difficulté, puis de sélectionner un puzzle aléatoire parmi les puzzles résolvables en fonction de la difficulté. De cette façon, vous serez certain que chaque casse-tête est résoluble, que la difficulté est prévisible et que la génération se fera dans un temps constant.
la source